diff --git a/.storybook/main.ts b/.storybook/main.ts index 3a0265ed..61de4301 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -15,6 +15,12 @@ const config: StorybookConfig = { {name: '@storybook/addon-essentials', options: {backgrounds: false}}, './theme-addon/register.tsx', ], + refs: { + 'gravity-charts': { + title: 'Gravity Charts', + url: 'https://preview.gravity-ui.com/charts', + }, + }, }; export default config; diff --git a/package-lock.json b/package-lock.json index f8f69349..caf7b012 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,11 @@ "license": "MIT", "dependencies": { "@bem-react/classname": "^1.6.0", + "@gravity-ui/charts": "^0.2.0", "@gravity-ui/date-utils": "^2.1.0", "@gravity-ui/i18n": "^1.0.0", "@gravity-ui/yagr": "^4.3.4", "afterframe": "^1.0.2", - "d3": "^7.8.5", "lodash": "^4.17.21", "react-split-pane": "^0.1.92", "tslib": "^2.6.2" @@ -47,6 +47,7 @@ "@typescript-eslint/eslint-plugin": "^5.31.0", "cross-env": "^7.0.3", "css-loader": "^5.2.7", + "d3": "^7.9.0", "eslint": "^8.56.0", "gulp": "^4.0.2", "gulp-cli": "^2.3.0", @@ -3010,10 +3011,28 @@ "@floating-ui/core": "^1.3.1" } }, + "node_modules/@gravity-ui/charts": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/charts/-/charts-0.2.0.tgz", + "integrity": "sha512-/UzRu15UExTguNa4VnpkciM6ns8alvBHpEicw+X4WPeThNCQ5ryGOvUcXAMcNjLpswYZTSY0nOpOpBTjuMA2eQ==", + "dependencies": { + "@bem-react/classname": "^1.6.0", + "@gravity-ui/date-utils": "^2.5.4", + "@gravity-ui/i18n": "^1.6.0", + "d3": "^7.9.0", + "lodash": "^4.17.21", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@gravity-ui/uikit": "^6.0.0", + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/@gravity-ui/date-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.1.0.tgz", - "integrity": "sha512-f7PsINb3/Q4gDDNZnZkE5SjDQqCba6NKa1e4W6976Zc7MkJ8fNTDnhC8sQP3Xpgme/yXAOx6U1rAJiijFaJY9Q==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@gravity-ui/date-utils/-/date-utils-2.5.5.tgz", + "integrity": "sha512-82IzJwmOaDqrJVa7IXOhWqI60epNx63gseiRhUOMDfAza+ra4tRORfTNa9ofV/lGYW5DVqoWJulMNpzDU0cM2g==", "dependencies": { "dayjs": "1.11.10", "lodash": "^4.17.0" @@ -3216,9 +3235,9 @@ "dev": true }, "node_modules/@gravity-ui/i18n": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/i18n/-/i18n-1.2.0.tgz", - "integrity": "sha512-1FNZmbxeT3arwU2bv1p77u/K7rYoX4pGrXf0SNwg45HbbgI0XV0WapXbWr/GIB7EXdjiOvQ7kzXCfVIFV4ifYw==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/i18n/-/i18n-1.6.0.tgz", + "integrity": "sha512-ftMLGZy7migLEtPkZa8jM6onipIeEOnEg9976RRpg3f39H+Q2bYYAGMjU+NJpWQ90ZDp6ztYLt5WAMEg248tEg==" }, "node_modules/@gravity-ui/icons": { "version": "2.8.1", @@ -11001,9 +11020,9 @@ } }, "node_modules/d3": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", - "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", "dependencies": { "d3-array": "3", "d3-axis": "3", diff --git a/package.json b/package.json index ed5ddb2f..d8e358e7 100644 --- a/package.json +++ b/package.json @@ -47,11 +47,11 @@ ], "dependencies": { "@bem-react/classname": "^1.6.0", + "@gravity-ui/charts": "^0.2.0", "@gravity-ui/date-utils": "^2.1.0", "@gravity-ui/i18n": "^1.0.0", "@gravity-ui/yagr": "^4.3.4", "afterframe": "^1.0.2", - "d3": "^7.8.5", "lodash": "^4.17.21", "react-split-pane": "^0.1.92", "tslib": "^2.6.2" @@ -84,6 +84,7 @@ "@typescript-eslint/eslint-plugin": "^5.31.0", "cross-env": "^7.0.3", "css-loader": "^5.2.7", + "d3": "^7.9.0", "eslint": "^8.56.0", "gulp": "^4.0.2", "gulp-cli": "^2.3.0", diff --git a/src/components/ChartKit.scss b/src/components/ChartKit.scss index 9d10f844..91171a3f 100644 --- a/src/components/ChartKit.scss +++ b/src/components/ChartKit.scss @@ -28,6 +28,4 @@ --highcharts-tooltip-alternate-bg: var(--g-color-base-generic); --highcharts-tooltip-text-complementary: var(--g-color-text-secondary); --highcharts-holiday-band: var(--g-color-base-generic); - - --d3-data-labels: var(--g-color-text-secondary); } diff --git a/src/plugins/d3/__stories__/Showcase.stories.tsx b/src/plugins/d3/__stories__/Showcase.stories.tsx deleted file mode 100644 index f198a285..00000000 --- a/src/plugins/d3/__stories__/Showcase.stories.tsx +++ /dev/null @@ -1,209 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row, Text} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {Loader} from '../../../components/Loader/Loader'; -import {settings} from '../../../libs'; -import {Basic as BasicArea} from '../examples/area/Basic'; -import {NegativeValues as AreaNegativeValues} from '../examples/area/NegativeValues'; -import {PercentStackingArea} from '../examples/area/PercentStacking'; -import {StackedArea} from '../examples/area/StackedArea'; -import {TwoYAxis as AreaTwoYAxis} from '../examples/area/TwoYAxis'; -import {BasicBarXChart} from '../examples/bar-x/Basic'; -import {DataLabels as BarXDataLabels} from '../examples/bar-x/DataLabels'; -import {GroupedColumns} from '../examples/bar-x/GroupedColumns'; -import {NegativeValues as BarXNegativeValues} from '../examples/bar-x/NegativeValues'; -import {PercentStackColumns} from '../examples/bar-x/PercentStack'; -import {StackedColumns} from '../examples/bar-x/StackedColumns'; -import {TwoYAxis as BarXTwoYAxis} from '../examples/bar-x/TwoYAxis'; -import {Basic as BasicBarY} from '../examples/bar-y/Basic'; -import {GroupedColumns as GroupedColumnsBarY} from '../examples/bar-y/GroupedColumns'; -import {NegativeValues as BarYNegativeValues} from '../examples/bar-y/NegativeValues'; -import {PercentStackingBars} from '../examples/bar-y/PercentStacking'; -import {StackedColumns as StackedColumnsBarY} from '../examples/bar-y/StackedColumns'; -import {LineAndBarXCombinedChart} from '../examples/combined/LineAndBarX'; -import {Basic as BasicLine} from '../examples/line/Basic'; -import {DataLabels as LineWithDataLabels} from '../examples/line/DataLabels'; -import {LineWithMarkers} from '../examples/line/LineWithMarkers'; -import {LinesWithShapes} from '../examples/line/Shapes'; -import {TwoYAxis as LineTwoYAxis} from '../examples/line/TwoYAxis'; -import {BasicPie} from '../examples/pie/Basic'; -import {Donut} from '../examples/pie/Donut'; -import {Basic as BasicScatter} from '../examples/scatter/Basic'; -import {TwoYAxis as ScatterTwoYAxis} from '../examples/scatter/TwoYAxis'; -import {D3Plugin} from '../index'; - -const ShowcaseStory = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - return ( -
- {loading ? ( - - ) : ( - - - Line charts - - - - Basic line chart - - - - With markers - - - - With data labels - - - - Lines with different shapes - - - - Line with two Y axis - - - - - Area charts - - - - Basic area chart - - - - Stacked area - - - - Stacked percentage areas - - - - Dual Y axis - - - - With negative values - - - - - Bar-x charts - - - - Basic column chart - - - - Grouped columns - - - - Stacked columns(normal) - - - - Stacked percentage column - - - - Bar-x chart with data labels - - - - Dual Y axis - - - - Bar-x chart with negative values - - - - - Bar-y charts - - - - Basic bar chart - - - - Grouped bars - - - - Stacked bars - - - - Stacked percentage bars - - - - Bar-y chart with negative values - - - - - Pie charts - - - - Basic pie chart - - - - Donut chart - - - - - Scatter charts - - - - Basic scatter - - - - Scatter chart with two Y axis - - - - - Combined charts - - - - Line + Bar-X - - - - - )} -
- ); -}; - -export const D3ShowcaseStory: StoryObj = { - name: 'Showcase', -}; - -export default { - title: 'Plugins/D3/Showcase', - decorators: [withKnobs], - component: ShowcaseStory, -}; diff --git a/src/plugins/d3/__stories__/area/Basic.stories.tsx b/src/plugins/d3/__stories__/area/Basic.stories.tsx deleted file mode 100644 index d9378e16..00000000 --- a/src/plugins/d3/__stories__/area/Basic.stories.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import {Basic} from '../../examples/area/Basic'; -import {PercentStackingArea} from '../../examples/area/PercentStacking'; -import {StackedArea} from '../../examples/area/StackedArea'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BasicAreaChartStory: StoryObj = { - name: 'Basic', - args: { - Chart: Basic, - }, -}; - -export const StackedAreaChartStory: StoryObj = { - name: 'Stacked', - args: { - Chart: StackedArea, - }, -}; - -export const PercentStackingAreaChartStory: StoryObj = { - name: 'Stacked percentage areas', - args: { - Chart: PercentStackingArea, - }, -}; - -export default { - title: 'Plugins/D3/Area', - decorators: [withKnobs], - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/area/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/area/HtmlLabels.stories.tsx deleted file mode 100644 index eb2e4937..00000000 --- a/src/plugins/d3/__stories__/area/HtmlLabels.stories.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const AreaWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const getLabelData = (value: string, color: string) => { - const labelStyle = `background: ${color};color: #fff;padding: 4px;border-radius: 4px;`; - return { - label: `${value}`, - }; - }; - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'area', - name: 'Series 1', - dataLabels: { - enabled: true, - html: true, - }, - data: [ - { - x: 1, - y: Math.random() * 1000, - ...getLabelData('First', '#4fc4b7'), - }, - { - x: 100, - y: Math.random() * 1000, - ...getLabelData('Last', '#8ccce3'), - }, - ], - }, - ], - }, - title: {text: 'Area with html labels'}, - }; - - return ( - - - - - - - - - - ); -}; - -export const AreaWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Area', - component: AreaWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/area/Playground.stories.tsx b/src/plugins/d3/__stories__/area/Playground.stories.tsx deleted file mode 100644 index 1096e306..00000000 --- a/src/plugins/d3/__stories__/area/Playground.stories.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; -import {HighchartsPlugin} from '../../../highcharts'; - -function prepareData(): ChartKitWidgetData { - return { - series: { - options: { - line: { - lineWidth: 2, - }, - }, - data: [ - { - name: 'A', - type: 'area', - data: [ - {x: 1, y: 200}, - {x: 2, y: 220}, - {x: 3, y: 180}, - ], - stacking: 'normal', - dataLabels: { - enabled: true, - }, - }, - { - name: 'B', - type: 'area', - data: [ - {x: 1, y: 30}, - {x: 2, y: 25}, - {x: 3, y: 45}, - ], - stacking: 'normal', - dataLabels: { - enabled: true, - }, - }, - ], - }, - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin, HighchartsPlugin]}); - return ; - } - - return ( - <> -
- -
- - ); -}; - -export const PlaygroundLineChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Area', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/bar-x/BarX.stories.tsx b/src/plugins/d3/__stories__/bar-x/BarX.stories.tsx deleted file mode 100644 index 28ec4593..00000000 --- a/src/plugins/d3/__stories__/bar-x/BarX.stories.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import { - BasicBarXChart, - BasicDateTimeBarXChart, - BasicLinearBarXChart, -} from '../../examples/bar-x/Basic'; -import {GroupedColumns} from '../../examples/bar-x/GroupedColumns'; -import {PercentStackColumns} from '../../examples/bar-x/PercentStack'; -import {StackedColumns} from '../../examples/bar-x/StackedColumns'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BasicBarXChartStory: StoryObj = { - name: 'Basic column chart', - args: { - Chart: BasicBarXChart, - }, -}; - -export const BasicLinearBarXChartStory: StoryObj = { - name: 'Linear X axis', - args: { - Chart: BasicLinearBarXChart, - }, -}; - -export const BasicDateTimeBarXChartStory: StoryObj = { - name: 'Datetime X axis', - args: { - Chart: BasicDateTimeBarXChart, - }, -}; - -export const GroupedBarXChartStory: StoryObj = { - name: 'Grouped columns', - args: { - Chart: GroupedColumns, - }, -}; - -export const StackedBarXChartStory: StoryObj = { - name: 'Stacked columns', - args: { - Chart: StackedColumns, - }, -}; - -export const PercentStackBarXChartStory: StoryObj = { - name: 'Stacked percentage columns', - args: { - Chart: PercentStackColumns, - }, -}; - -export default { - title: 'Plugins/D3/Bar-X', - decorators: [withKnobs], - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/bar-x/ContinuousLegend.stories.tsx b/src/plugins/d3/__stories__/bar-x/ContinuousLegend.stories.tsx deleted file mode 100644 index 27e488f8..00000000 --- a/src/plugins/d3/__stories__/bar-x/ContinuousLegend.stories.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import type {StoryObj} from '@storybook/react'; -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {BarXSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import nintendoGames from '../../examples/nintendoGames'; -import {D3Plugin} from '../../index'; -import {getContinuesColorFn} from '../../renderer/utils'; - -const BarXWithContinuousLegend = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const colors = ['rgb(255, 61, 100)', 'rgb(255, 198, 54)', 'rgb(84, 165, 32)']; - const stops = [0, 0.5, 1]; - - const gamesByPlatform = groups(nintendoGames, (item) => item.platform); - const categories = gamesByPlatform.map(([platform, _games]) => platform); - const data: BarXSeriesData[] = gamesByPlatform.map(([platform, games], index) => ({ - x: index, - y: games.length, - label: `${platform}(${games.length})`, - })); - const getColor = getContinuesColorFn({colors, stops, values: data.map((d) => Number(d.y))}); - data.forEach((d) => { - d.color = getColor(Number(d.y)); - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-x', - name: 'Series 1', - data, - }, - ], - }, - xAxis: { - type: 'category', - categories, - }, - title: {text: 'Bar-x with continues color'}, - legend: { - enabled: true, - type: 'continuous', - title: {text: 'Games by platform'}, - colorScale: { - colors: colors, - stops, - }, - }, - }; - - return ( - - - - ); -}; - -export const BarXWithContinuousLegendStory: StoryObj = { - name: 'Continuous legend', -}; - -export default { - title: 'Plugins/D3/Bar-x', - component: BarXWithContinuousLegend, -}; diff --git a/src/plugins/d3/__stories__/bar-x/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/bar-x/HtmlLabels.stories.tsx deleted file mode 100644 index 3e17393a..00000000 --- a/src/plugins/d3/__stories__/bar-x/HtmlLabels.stories.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const BarXWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const getLabelData = (value: string, color: string) => { - const labelStyle = `background: ${color};color: #fff;padding: 4px;border-radius: 4px;border: 1px solid #fff;`; - return { - label: `${value}`, - color, - }; - }; - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-x', - name: 'Series 1', - dataLabels: { - enabled: true, - html: true, - }, - data: [ - { - x: 0, - y: Math.random() * 1000, - ...getLabelData('First', '#4fc4b7'), - }, - { - x: 1, - y: Math.random() * 1000, - ...getLabelData('Last', '#8ccce3'), - }, - ], - }, - ], - }, - xAxis: {type: 'category', categories: ['First', 'Second']}, - title: {text: 'Bar-x with html labels'}, - }; - - return ( - - - - - - - - - - ); -}; - -export const BarXWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Bar-x', - component: BarXWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/bar-x/PerformanceIssue.stories.tsx b/src/plugins/d3/__stories__/bar-x/PerformanceIssue.stories.tsx deleted file mode 100644 index 6cde7d26..00000000 --- a/src/plugins/d3/__stories__/bar-x/PerformanceIssue.stories.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {randomNormal} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData} from '../../../../types'; -import {randomString} from '../../../../utils'; - -const randomFn = randomNormal(0, 10); -const randomStr = () => randomString(Math.random() * 10, 'absdEFGHIJklmnopqrsTUvWxyz'); - -const ChartStory = (args: {pointsCount: number; seriesCount: number}) => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - - const widgetData: ChartKitWidgetData = React.useMemo(() => { - const points = Array.from({length: args.pointsCount}).map(() => - Math.ceil(Math.abs(randomFn())), - ); - const series = Array.from({length: args.seriesCount}).map(randomStr); - - return { - series: { - data: series.map((s) => ({ - type: 'bar-x', - stacking: 'normal', - name: s, - data: points.map((p, i) => ({ - x: i, - y: p, - })), - })), - }, - }; - }, [args]); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PerformanceIssueScatter: StoryObj = { - name: 'Performance issue', - args: { - pointsCount: 1000, - seriesCount: 10, - }, - argTypes: { - pointsCount: { - control: 'number', - }, - }, -}; - -export default { - title: 'Plugins/D3/Bar-X', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/bar-x/Playground.stories.tsx b/src/plugins/d3/__stories__/bar-x/Playground.stories.tsx deleted file mode 100644 index 67ecffe4..00000000 --- a/src/plugins/d3/__stories__/bar-x/Playground.stories.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {groups} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData(): ChartKitWidgetData { - const gamesByPlatform = groups(nintendoGames, (item) => item['platform']); - const data = gamesByPlatform.map(([value, games]) => ({ - x: value, - y: games.length, - })); - - return { - series: { - data: [ - { - type: 'bar-x', - data, - name: 'Games released', - }, - ], - }, - xAxis: { - type: 'category', - categories: gamesByPlatform.map(([key, _group]) => key), - title: { - text: 'Game Platforms', - }, - labels: { - enabled: true, - rotation: 30, - }, - }, - yAxis: [ - { - title: {text: 'Number of games released'}, - labels: { - enabled: true, - rotation: -90, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PlaygroundBarXChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Bar-X', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/bar-y/BarY.stories.tsx b/src/plugins/d3/__stories__/bar-y/BarY.stories.tsx deleted file mode 100644 index 665867c9..00000000 --- a/src/plugins/d3/__stories__/bar-y/BarY.stories.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import {Basic} from '../../examples/bar-y/Basic'; -import {GroupedColumns} from '../../examples/bar-y/GroupedColumns'; -import {PercentStackingBars} from '../../examples/bar-y/PercentStacking'; -import {StackedColumns} from '../../examples/bar-y/StackedColumns'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BasicBarYChartStory: StoryObj = { - name: 'Basic', - args: { - Chart: Basic, - }, -}; - -export const GroupedBarYChartStory: StoryObj = { - name: 'Grouped bars', - args: { - Chart: GroupedColumns, - }, -}; - -export const StackedBarYChartStory: StoryObj = { - name: 'Stacked bars', - args: { - Chart: StackedColumns, - }, -}; - -export const PercentStackingBarYChartStory: StoryObj = { - name: 'Stacked percentage bars', - args: { - Chart: PercentStackingBars, - }, -}; - -export default { - title: 'Plugins/D3/Bar-Y', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/bar-y/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/bar-y/HtmlLabels.stories.tsx deleted file mode 100644 index a5e55381..00000000 --- a/src/plugins/d3/__stories__/bar-y/HtmlLabels.stories.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const BarYWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const getLabelData = (value: string, color: string) => { - const labelStyle = `background: ${color};color: #fff;padding: 4px;border-radius: 4px;border: 1px solid #fff;`; - return { - label: `${value}`, - color, - }; - }; - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-y', - name: 'Series 1', - dataLabels: { - enabled: true, - html: true, - }, - data: [ - { - y: 0, - x: Math.random() * 1000, - ...getLabelData('First', '#4fc4b7'), - }, - { - y: 1, - x: Math.random() * 1000, - ...getLabelData('Last', '#8ccce3'), - }, - ], - }, - ], - }, - yAxis: [{type: 'category', categories: ['First', 'Second']}], - title: {text: 'Bar-y with html labels'}, - }; - - return ( - - - - - - - - - - ); -}; - -export const BarYWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Bar-y', - component: BarYWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/bar-y/Playground.stories.tsx b/src/plugins/d3/__stories__/bar-y/Playground.stories.tsx deleted file mode 100644 index 04656746..00000000 --- a/src/plugins/d3/__stories__/bar-y/Playground.stories.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {groups} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData(): ChartKitWidgetData { - const gamesByPlatform = groups(nintendoGames, (item) => item['platform']); - const data = gamesByPlatform.map(([value, games]) => ({ - x: games.length, - y: value, - })); - - return { - series: { - data: [ - { - type: 'bar-y', - data, - name: 'Games released', - dataLabels: { - enabled: true, - }, - }, - ], - }, - xAxis: { - title: {text: 'Number of games released'}, - labels: { - enabled: true, - }, - lineColor: 'transparent', - }, - yAxis: [ - { - type: 'category', - categories: gamesByPlatform.map(([key]) => key), - title: { - text: 'Game Platforms', - }, - labels: { - enabled: true, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PlaygroundBarYChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Bar-Y', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/combined/LineAndBarX.stories.tsx b/src/plugins/d3/__stories__/combined/LineAndBarX.stories.tsx deleted file mode 100644 index dcb5719f..00000000 --- a/src/plugins/d3/__stories__/combined/LineAndBarX.stories.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import {LineAndBarXCombinedChart} from '../../examples/combined/LineAndBarX'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const LineAndBarXCombinedChartStory: StoryObj = { - name: 'Line and Bar-x combined chart', - args: { - Chart: LineAndBarXCombinedChart, - }, -}; - -export default { - title: 'Plugins/D3/Combined', - decorators: [withKnobs], - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/line/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/line/HtmlLabels.stories.tsx deleted file mode 100644 index a2db3476..00000000 --- a/src/plugins/d3/__stories__/line/HtmlLabels.stories.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const LineWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const getLabelData = (value: string, color: string) => { - const labelStyle = `background: ${color};color: #fff;padding: 4px;border-radius: 4px;`; - return { - label: `${value}`, - }; - }; - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'line', - name: 'Series 1', - dataLabels: { - enabled: true, - html: true, - }, - data: [ - { - x: 1, - y: Math.random() * 1000, - ...getLabelData('First', '#4fc4b7'), - }, - { - x: 100, - y: Math.random() * 1000, - ...getLabelData('Last', '#8ccce3'), - }, - ], - }, - ], - }, - title: {text: 'Line with html labels'}, - }; - - return ( - - - - - - - - - - ); -}; - -export const LineWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Line', - component: LineWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/line/Line.stories.tsx b/src/plugins/d3/__stories__/line/Line.stories.tsx deleted file mode 100644 index 12ddf2ee..00000000 --- a/src/plugins/d3/__stories__/line/Line.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; - -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import {LineWithLogarithmicAxis} from '../../examples/line/LogarithmicAxis'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - return ( -
- -
- ); -}; - -export const LogarithmicAxis: StoryObj = { - name: 'Logarithmic axis', - args: { - Chart: LineWithLogarithmicAxis, - }, -}; - -export default { - title: 'Plugins/D3/Line', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/line/PerformanceIssue.stories.tsx b/src/plugins/d3/__stories__/line/PerformanceIssue.stories.tsx deleted file mode 100644 index a4ff7ee0..00000000 --- a/src/plugins/d3/__stories__/line/PerformanceIssue.stories.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {randomNormal} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData} from '../../../../types'; -import {randomString} from '../../../../utils'; - -const randomFn = randomNormal(0, 10); -const randomStr = () => randomString(Math.random() * 10, 'absdEFGHIJklmnopqrsTUvWxyz'); - -const ChartStory = (args: {pointsCount: number; seriesCount: number}) => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - - const widgetData: ChartKitWidgetData = React.useMemo(() => { - const points = Array.from({length: args.pointsCount}).map(() => Math.abs(randomFn())); - const series = Array.from({length: args.seriesCount}).map(randomStr); - - return { - series: { - data: series.map((s) => ({ - type: 'line', - name: s, - data: points.map((_, i) => ({ - x: i, - y: randomFn(), - })), - })), - }, - }; - }, [args]); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PerformanceIssueScatter: StoryObj = { - name: 'Performance issue', - args: { - pointsCount: 5000, - seriesCount: 2, - }, - argTypes: { - pointsCount: { - control: 'number', - }, - }, -}; - -export default { - title: 'Plugins/D3/Line', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/line/Playground.stories.tsx b/src/plugins/d3/__stories__/line/Playground.stories.tsx deleted file mode 100644 index ed677fdd..00000000 --- a/src/plugins/d3/__stories__/line/Playground.stories.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData, LineSeriesData} from '../../../../types'; -import {HighchartsPlugin} from '../../../highcharts'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData(): ChartKitWidgetData { - const games = nintendoGames.filter((d) => { - return d.date && d.user_score; - }); - - const byGenre = (genre: string) => { - return games - .filter((d) => d.genres.includes(genre)) - .map((d) => { - return { - x: d.date, - y: d.user_score, - label: d.title, - }; - }) as LineSeriesData[]; - }; - - return { - series: { - options: { - line: { - lineWidth: 2, - }, - }, - data: [ - { - name: '3D', - type: 'line', - data: byGenre('3D'), - dataLabels: { - enabled: true, - }, - }, - { - name: '2D', - type: 'line', - data: byGenre('2D'), - dataLabels: { - enabled: true, - }, - }, - { - name: 'Strategy', - type: 'line', - data: byGenre('Strategy'), - dataLabels: { - enabled: true, - }, - }, - { - name: 'Shooter', - type: 'line', - data: byGenre('Shooter'), - dataLabels: { - enabled: true, - }, - }, - ], - }, - xAxis: { - type: 'datetime', - title: { - text: 'Release date', - }, - }, - yAxis: [ - { - title: {text: 'User score'}, - labels: { - enabled: true, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin, HighchartsPlugin]}); - return ; - } - - return ( - <> -
- -
-
- -
- - ); -}; - -export const PlaygroundLineChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Line', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/line/Split.stories.tsx b/src/plugins/d3/__stories__/line/Split.stories.tsx deleted file mode 100644 index 7def385f..00000000 --- a/src/plugins/d3/__stories__/line/Split.stories.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React from 'react'; - -import {action} from '@storybook/addon-actions'; -import type {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData, LineSeries, LineSeriesData} from '../../../../types'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData(): LineSeries[] { - const games = nintendoGames.filter((d) => { - return d.date && d.user_score; - }); - - const byGenre = (genre: string) => { - return games - .filter((d) => d.genres.includes(genre)) - .map((d) => { - const releaseDate = new Date(d.date as number); - return { - x: releaseDate.getFullYear(), - y: d.user_score, - label: `${d.title} (${d.user_score})`, - custom: d, - }; - }) as LineSeriesData[]; - }; - - return [ - { - name: 'Strategy', - type: 'line', - data: byGenre('Strategy'), - yAxis: 0, - }, - { - name: 'Shooter', - type: 'line', - data: byGenre('Shooter'), - yAxis: 1, - }, - { - name: 'Puzzle', - type: 'line', - data: byGenre('Puzzle'), - yAxis: 1, - }, - ]; -} - -const ChartStory = () => { - const [loading, setLoading] = React.useState(true); - const chartkitRef = React.useRef(); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - const widgetData: ChartKitWidgetData = { - title: { - text: 'Chart title', - }, - series: { - data: prepareData(), - }, - split: { - enable: true, - layout: 'vertical', - gap: '40px', - plots: [{title: {text: 'Strategy'}}, {title: {text: 'Shooter & Puzzle'}}], - }, - yAxis: [ - { - title: {text: '1'}, - plotIndex: 0, - }, - { - title: {text: '2'}, - plotIndex: 1, - }, - ], - xAxis: { - type: 'linear', - labels: { - numberFormat: { - showRankDelimiter: false, - }, - }, - }, - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; - - if (loading) { - return ; - } - - return ( -
- -
- ); -}; - -export const Split: StoryObj = { - name: 'Split', -}; - -export default { - title: 'Plugins/D3/Line', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/other/AxisTitle.stories.tsx b/src/plugins/d3/__stories__/other/AxisTitle.stories.tsx deleted file mode 100644 index 432cbb46..00000000 --- a/src/plugins/d3/__stories__/other/AxisTitle.stories.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row, Text} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetAxis, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const AxisTitle = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const longText = `One dollar and eighty-seven cents. That was all. - And sixty cents of it was in pennies. Pennies saved one and two at a time by bulldozing - the grocer and the vegetable man and the butcher until one's cheeks burned with the silent - imputation of parsimony that such close dealing implied. Three times Della counted it. - One dollar and eighty - seven cents.`; - const getWidgetData = (title: ChartKitWidgetAxis['title']): ChartKitWidgetData => ({ - yAxis: [ - { - title, - }, - ], - xAxis: { - title, - }, - series: { - data: [ - { - type: 'line', - name: 'Line series', - data: [ - {x: 1, y: 10}, - {x: 2, y: 100}, - ], - }, - ], - }, - }); - - return ( - - - Text alignment - - - - - - - - - - - - - - - - - - - - Long text - - - - - - - - - - - - - - - ); -}; - -export const AxisTitleStory: StoryObj = { - name: 'Axis title', -}; - -export default { - title: 'Plugins/D3/other', - component: AxisTitle, -}; diff --git a/src/plugins/d3/__stories__/penguins.json b/src/plugins/d3/__stories__/penguins.json deleted file mode 100644 index 889c072a..00000000 --- a/src/plugins/d3/__stories__/penguins.json +++ /dev/null @@ -1,3098 +0,0 @@ -[ - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.1, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 181, - "body_mass_g": 3750, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.5, - "culmen_depth_mm": 17.4, - "flipper_length_mm": 186, - "body_mass_g": 3800, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 40.3, - "culmen_depth_mm": 18, - "flipper_length_mm": 195, - "body_mass_g": 3250, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": null, - "culmen_depth_mm": null, - "flipper_length_mm": null, - "body_mass_g": null, - "sex": null - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 36.7, - "culmen_depth_mm": 19.3, - "flipper_length_mm": 193, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.3, - "culmen_depth_mm": 20.6, - "flipper_length_mm": 190, - "body_mass_g": 3650, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.9, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 181, - "body_mass_g": 3625, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.2, - "culmen_depth_mm": 19.6, - "flipper_length_mm": 195, - "body_mass_g": 4675, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 34.1, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 193, - "body_mass_g": 3475, - "sex": null - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 42, - "culmen_depth_mm": 20.2, - "flipper_length_mm": 190, - "body_mass_g": 4250, - "sex": null - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 37.8, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 186, - "body_mass_g": 3300, - "sex": null - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 37.8, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 180, - "body_mass_g": 3700, - "sex": null - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 17.6, - "flipper_length_mm": 182, - "body_mass_g": 3200, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.6, - "culmen_depth_mm": 21.2, - "flipper_length_mm": 191, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 34.6, - "culmen_depth_mm": 21.1, - "flipper_length_mm": 198, - "body_mass_g": 4400, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 36.6, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 185, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.7, - "culmen_depth_mm": 19, - "flipper_length_mm": 195, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 42.5, - "culmen_depth_mm": 20.7, - "flipper_length_mm": 197, - "body_mass_g": 4500, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 34.4, - "culmen_depth_mm": 18.4, - "flipper_length_mm": 184, - "body_mass_g": 3325, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 46, - "culmen_depth_mm": 21.5, - "flipper_length_mm": 194, - "body_mass_g": 4200, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.8, - "culmen_depth_mm": 18.3, - "flipper_length_mm": 174, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.7, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 180, - "body_mass_g": 3600, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35.9, - "culmen_depth_mm": 19.2, - "flipper_length_mm": 189, - "body_mass_g": 3800, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.2, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 185, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.8, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 180, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35.3, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 187, - "body_mass_g": 3800, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 40.6, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 183, - "body_mass_g": 3550, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 40.5, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 187, - "body_mass_g": 3200, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.9, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 172, - "body_mass_g": 3150, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 40.5, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 180, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.5, - "culmen_depth_mm": 16.7, - "flipper_length_mm": 178, - "body_mass_g": 3250, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.2, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 178, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.5, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 188, - "body_mass_g": 3300, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.9, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 184, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.4, - "culmen_depth_mm": 17, - "flipper_length_mm": 195, - "body_mass_g": 3325, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.2, - "culmen_depth_mm": 21.1, - "flipper_length_mm": 196, - "body_mass_g": 4150, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 38.8, - "culmen_depth_mm": 20, - "flipper_length_mm": 190, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 42.2, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 180, - "body_mass_g": 3550, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.6, - "culmen_depth_mm": 19.3, - "flipper_length_mm": 181, - "body_mass_g": 3300, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.8, - "culmen_depth_mm": 19.1, - "flipper_length_mm": 184, - "body_mass_g": 4650, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.5, - "culmen_depth_mm": 18, - "flipper_length_mm": 182, - "body_mass_g": 3150, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.8, - "culmen_depth_mm": 18.4, - "flipper_length_mm": 195, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 186, - "body_mass_g": 3100, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 44.1, - "culmen_depth_mm": 19.7, - "flipper_length_mm": 196, - "body_mass_g": 4400, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37, - "culmen_depth_mm": 16.9, - "flipper_length_mm": 185, - "body_mass_g": 3000, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.6, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 190, - "body_mass_g": 4600, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 19, - "flipper_length_mm": 182, - "body_mass_g": 3425, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.5, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 179, - "body_mass_g": 2975, - "sex": null - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 190, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 42.3, - "culmen_depth_mm": 21.2, - "flipper_length_mm": 191, - "body_mass_g": 4150, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 39.6, - "culmen_depth_mm": 17.7, - "flipper_length_mm": 186, - "body_mass_g": 3500, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 40.1, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 188, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 190, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 42, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 200, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 34.5, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 187, - "body_mass_g": 2900, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41.4, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 191, - "body_mass_g": 3700, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 39, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 186, - "body_mass_g": 3550, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 40.6, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 193, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 36.5, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 181, - "body_mass_g": 2850, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.6, - "culmen_depth_mm": 19.1, - "flipper_length_mm": 194, - "body_mass_g": 3750, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35.7, - "culmen_depth_mm": 16.9, - "flipper_length_mm": 185, - "body_mass_g": 3150, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41.3, - "culmen_depth_mm": 21.1, - "flipper_length_mm": 195, - "body_mass_g": 4400, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.6, - "culmen_depth_mm": 17, - "flipper_length_mm": 185, - "body_mass_g": 3600, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 18.2, - "flipper_length_mm": 192, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 36.4, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 184, - "body_mass_g": 2850, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41.6, - "culmen_depth_mm": 18, - "flipper_length_mm": 192, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35.5, - "culmen_depth_mm": 16.2, - "flipper_length_mm": 195, - "body_mass_g": 3350, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 19.1, - "flipper_length_mm": 188, - "body_mass_g": 4100, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 35.9, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 190, - "body_mass_g": 3050, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 41.8, - "culmen_depth_mm": 19.4, - "flipper_length_mm": 198, - "body_mass_g": 4450, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 33.5, - "culmen_depth_mm": 19, - "flipper_length_mm": 190, - "body_mass_g": 3600, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.7, - "culmen_depth_mm": 18.4, - "flipper_length_mm": 190, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39.6, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 196, - "body_mass_g": 3550, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 45.8, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 197, - "body_mass_g": 4150, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 35.5, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 190, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 42.8, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 195, - "body_mass_g": 4250, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 40.9, - "culmen_depth_mm": 16.8, - "flipper_length_mm": 191, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 37.2, - "culmen_depth_mm": 19.4, - "flipper_length_mm": 184, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 36.2, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 187, - "body_mass_g": 3550, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 42.1, - "culmen_depth_mm": 19.1, - "flipper_length_mm": 195, - "body_mass_g": 4000, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 34.6, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 189, - "body_mass_g": 3200, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 42.9, - "culmen_depth_mm": 17.6, - "flipper_length_mm": 196, - "body_mass_g": 4700, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 36.7, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 187, - "body_mass_g": 3800, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 35.1, - "culmen_depth_mm": 19.4, - "flipper_length_mm": 193, - "body_mass_g": 4200, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.3, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 191, - "body_mass_g": 3350, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 41.3, - "culmen_depth_mm": 20.3, - "flipper_length_mm": 194, - "body_mass_g": 3550, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.3, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 190, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.9, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 189, - "body_mass_g": 3500, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 38.3, - "culmen_depth_mm": 19.2, - "flipper_length_mm": 189, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 38.9, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 190, - "body_mass_g": 3600, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 35.7, - "culmen_depth_mm": 18, - "flipper_length_mm": 202, - "body_mass_g": 3550, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 205, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 34, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 185, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.6, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 186, - "body_mass_g": 4450, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.2, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 187, - "body_mass_g": 3300, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.8, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 208, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 38.1, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 190, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.3, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 196, - "body_mass_g": 4350, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 33.1, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 178, - "body_mass_g": 2900, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 43.2, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 192, - "body_mass_g": 4100, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 35, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 192, - "body_mass_g": 3725, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 41, - "culmen_depth_mm": 20, - "flipper_length_mm": 203, - "body_mass_g": 4725, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.7, - "culmen_depth_mm": 16, - "flipper_length_mm": 183, - "body_mass_g": 3075, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.8, - "culmen_depth_mm": 20, - "flipper_length_mm": 190, - "body_mass_g": 4250, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 37.9, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 193, - "body_mass_g": 2925, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 39.7, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 184, - "body_mass_g": 3550, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.6, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 199, - "body_mass_g": 3750, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.2, - "culmen_depth_mm": 20, - "flipper_length_mm": 190, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.1, - "culmen_depth_mm": 17, - "flipper_length_mm": 181, - "body_mass_g": 3175, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 43.2, - "culmen_depth_mm": 19, - "flipper_length_mm": 197, - "body_mass_g": 4775, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 38.1, - "culmen_depth_mm": 16.5, - "flipper_length_mm": 198, - "body_mass_g": 3825, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 45.6, - "culmen_depth_mm": 20.3, - "flipper_length_mm": 191, - "body_mass_g": 4600, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 39.7, - "culmen_depth_mm": 17.7, - "flipper_length_mm": 193, - "body_mass_g": 3200, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 42.2, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 197, - "body_mass_g": 4275, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 39.6, - "culmen_depth_mm": 20.7, - "flipper_length_mm": 191, - "body_mass_g": 3900, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Biscoe", - "culmen_length_mm": 42.7, - "culmen_depth_mm": 18.3, - "flipper_length_mm": 196, - "body_mass_g": 4075, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.6, - "culmen_depth_mm": 17, - "flipper_length_mm": 188, - "body_mass_g": 2900, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 37.3, - "culmen_depth_mm": 20.5, - "flipper_length_mm": 199, - "body_mass_g": 3775, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 35.7, - "culmen_depth_mm": 17, - "flipper_length_mm": 189, - "body_mass_g": 3350, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 189, - "body_mass_g": 3325, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 36.2, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 187, - "body_mass_g": 3150, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 37.7, - "culmen_depth_mm": 19.8, - "flipper_length_mm": 198, - "body_mass_g": 3500, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 40.2, - "culmen_depth_mm": 17, - "flipper_length_mm": 176, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 41.4, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 202, - "body_mass_g": 3875, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 35.2, - "culmen_depth_mm": 15.9, - "flipper_length_mm": 186, - "body_mass_g": 3050, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 40.6, - "culmen_depth_mm": 19, - "flipper_length_mm": 199, - "body_mass_g": 4000, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.8, - "culmen_depth_mm": 17.6, - "flipper_length_mm": 191, - "body_mass_g": 3275, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 41.5, - "culmen_depth_mm": 18.3, - "flipper_length_mm": 195, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 39, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 191, - "body_mass_g": 3050, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 44.1, - "culmen_depth_mm": 18, - "flipper_length_mm": 210, - "body_mass_g": 4000, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 38.5, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 190, - "body_mass_g": 3325, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Torgersen", - "culmen_length_mm": 43.1, - "culmen_depth_mm": 19.2, - "flipper_length_mm": 197, - "body_mass_g": 3500, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.8, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 193, - "body_mass_g": 3500, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.5, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 199, - "body_mass_g": 4475, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 38.1, - "culmen_depth_mm": 17.6, - "flipper_length_mm": 187, - "body_mass_g": 3425, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 41.1, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 190, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 35.6, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 191, - "body_mass_g": 3175, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.2, - "culmen_depth_mm": 20.1, - "flipper_length_mm": 200, - "body_mass_g": 3975, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37, - "culmen_depth_mm": 16.5, - "flipper_length_mm": 185, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.7, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 193, - "body_mass_g": 4250, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.2, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 193, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.6, - "culmen_depth_mm": 17.2, - "flipper_length_mm": 187, - "body_mass_g": 3475, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 32.1, - "culmen_depth_mm": 15.5, - "flipper_length_mm": 188, - "body_mass_g": 3050, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 40.7, - "culmen_depth_mm": 17, - "flipper_length_mm": 190, - "body_mass_g": 3725, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.3, - "culmen_depth_mm": 16.8, - "flipper_length_mm": 192, - "body_mass_g": 3000, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 185, - "body_mass_g": 3650, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 39.2, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 190, - "body_mass_g": 4250, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36.6, - "culmen_depth_mm": 18.4, - "flipper_length_mm": 184, - "body_mass_g": 3475, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 195, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 37.8, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 193, - "body_mass_g": 3750, - "sex": "MALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 36, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 187, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Adelie", - "island": "Dream", - "culmen_length_mm": 41.5, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 201, - "body_mass_g": 4000, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.5, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 192, - "body_mass_g": 3500, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 196, - "body_mass_g": 3900, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.3, - "culmen_depth_mm": 19.2, - "flipper_length_mm": 193, - "body_mass_g": 3650, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.4, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 188, - "body_mass_g": 3525, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52.7, - "culmen_depth_mm": 19.8, - "flipper_length_mm": 197, - "body_mass_g": 3725, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 198, - "body_mass_g": 3950, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.1, - "culmen_depth_mm": 18.2, - "flipper_length_mm": 178, - "body_mass_g": 3250, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.3, - "culmen_depth_mm": 18.2, - "flipper_length_mm": 197, - "body_mass_g": 3750, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46, - "culmen_depth_mm": 18.9, - "flipper_length_mm": 195, - "body_mass_g": 4150, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.3, - "culmen_depth_mm": 19.9, - "flipper_length_mm": 198, - "body_mass_g": 3700, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.6, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 193, - "body_mass_g": 3800, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.7, - "culmen_depth_mm": 20.3, - "flipper_length_mm": 194, - "body_mass_g": 3775, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 47, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 185, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 201, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.9, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 190, - "body_mass_g": 3575, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.5, - "culmen_depth_mm": 19.6, - "flipper_length_mm": 201, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.3, - "culmen_depth_mm": 20, - "flipper_length_mm": 197, - "body_mass_g": 3300, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 58, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 181, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.4, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 190, - "body_mass_g": 3450, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.2, - "culmen_depth_mm": 18.2, - "flipper_length_mm": 195, - "body_mass_g": 4400, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 42.4, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 181, - "body_mass_g": 3600, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 48.5, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 191, - "body_mass_g": 3400, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 43.2, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 187, - "body_mass_g": 2900, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.6, - "culmen_depth_mm": 19.4, - "flipper_length_mm": 193, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.7, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 195, - "body_mass_g": 3300, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52, - "culmen_depth_mm": 19, - "flipper_length_mm": 197, - "body_mass_g": 4150, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.5, - "culmen_depth_mm": 18.4, - "flipper_length_mm": 200, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.5, - "culmen_depth_mm": 19, - "flipper_length_mm": 200, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.4, - "culmen_depth_mm": 17.8, - "flipper_length_mm": 191, - "body_mass_g": 3700, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52.8, - "culmen_depth_mm": 20, - "flipper_length_mm": 205, - "body_mass_g": 4550, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 40.9, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 187, - "body_mass_g": 3200, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 54.2, - "culmen_depth_mm": 20.8, - "flipper_length_mm": 201, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 42.5, - "culmen_depth_mm": 16.7, - "flipper_length_mm": 187, - "body_mass_g": 3350, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 203, - "body_mass_g": 4100, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.7, - "culmen_depth_mm": 18.6, - "flipper_length_mm": 195, - "body_mass_g": 3600, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 47.5, - "culmen_depth_mm": 16.8, - "flipper_length_mm": 199, - "body_mass_g": 3900, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 47.6, - "culmen_depth_mm": 18.3, - "flipper_length_mm": 195, - "body_mass_g": 3850, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52, - "culmen_depth_mm": 20.7, - "flipper_length_mm": 210, - "body_mass_g": 4800, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.9, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 192, - "body_mass_g": 2700, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 53.5, - "culmen_depth_mm": 19.9, - "flipper_length_mm": 205, - "body_mass_g": 4500, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 210, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.2, - "culmen_depth_mm": 17.5, - "flipper_length_mm": 187, - "body_mass_g": 3650, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.9, - "culmen_depth_mm": 19.1, - "flipper_length_mm": 196, - "body_mass_g": 3550, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.5, - "culmen_depth_mm": 17, - "flipper_length_mm": 196, - "body_mass_g": 3500, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.9, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 196, - "body_mass_g": 3675, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.8, - "culmen_depth_mm": 18.5, - "flipper_length_mm": 201, - "body_mass_g": 4450, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.1, - "culmen_depth_mm": 17.9, - "flipper_length_mm": 190, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49, - "culmen_depth_mm": 19.6, - "flipper_length_mm": 212, - "body_mass_g": 4300, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.5, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 187, - "body_mass_g": 3250, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.8, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 198, - "body_mass_g": 3675, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 48.1, - "culmen_depth_mm": 16.4, - "flipper_length_mm": 199, - "body_mass_g": 3325, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.4, - "culmen_depth_mm": 19, - "flipper_length_mm": 201, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.7, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 193, - "body_mass_g": 3600, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.7, - "culmen_depth_mm": 19.7, - "flipper_length_mm": 203, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 42.5, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 187, - "body_mass_g": 3350, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 52.2, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 197, - "body_mass_g": 3450, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 16.6, - "flipper_length_mm": 191, - "body_mass_g": 3250, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.3, - "culmen_depth_mm": 19.9, - "flipper_length_mm": 203, - "body_mass_g": 4050, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.2, - "culmen_depth_mm": 18.8, - "flipper_length_mm": 202, - "body_mass_g": 3800, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.6, - "culmen_depth_mm": 19.4, - "flipper_length_mm": 194, - "body_mass_g": 3525, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 51.9, - "culmen_depth_mm": 19.5, - "flipper_length_mm": 206, - "body_mass_g": 3950, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 46.8, - "culmen_depth_mm": 16.5, - "flipper_length_mm": 189, - "body_mass_g": 3650, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 45.7, - "culmen_depth_mm": 17, - "flipper_length_mm": 195, - "body_mass_g": 3650, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 55.8, - "culmen_depth_mm": 19.8, - "flipper_length_mm": 207, - "body_mass_g": 4000, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 43.5, - "culmen_depth_mm": 18.1, - "flipper_length_mm": 202, - "body_mass_g": 3400, - "sex": "FEMALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 49.6, - "culmen_depth_mm": 18.2, - "flipper_length_mm": 193, - "body_mass_g": 3775, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.8, - "culmen_depth_mm": 19, - "flipper_length_mm": 210, - "body_mass_g": 4100, - "sex": "MALE" - }, - { - "species": "Chinstrap", - "island": "Dream", - "culmen_length_mm": 50.2, - "culmen_depth_mm": 18.7, - "flipper_length_mm": 198, - "body_mass_g": 3775, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.1, - "culmen_depth_mm": 13.2, - "flipper_length_mm": 211, - "body_mass_g": 4500, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50, - "culmen_depth_mm": 16.3, - "flipper_length_mm": 230, - "body_mass_g": 5700, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.7, - "culmen_depth_mm": 14.1, - "flipper_length_mm": 210, - "body_mass_g": 4450, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50, - "culmen_depth_mm": 15.2, - "flipper_length_mm": 218, - "body_mass_g": 5700, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.6, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 215, - "body_mass_g": 5400, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.5, - "culmen_depth_mm": 13.5, - "flipper_length_mm": 210, - "body_mass_g": 4550, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.4, - "culmen_depth_mm": 14.6, - "flipper_length_mm": 211, - "body_mass_g": 4800, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.7, - "culmen_depth_mm": 15.3, - "flipper_length_mm": 219, - "body_mass_g": 5200, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.3, - "culmen_depth_mm": 13.4, - "flipper_length_mm": 209, - "body_mass_g": 4400, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.8, - "culmen_depth_mm": 15.4, - "flipper_length_mm": 215, - "body_mass_g": 5150, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 40.9, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 214, - "body_mass_g": 4650, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 216, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.5, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 214, - "body_mass_g": 4650, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.4, - "culmen_depth_mm": 14.6, - "flipper_length_mm": 213, - "body_mass_g": 5850, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.8, - "culmen_depth_mm": 14.6, - "flipper_length_mm": 210, - "body_mass_g": 4200, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.3, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 217, - "body_mass_g": 5850, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 42, - "culmen_depth_mm": 13.5, - "flipper_length_mm": 210, - "body_mass_g": 4150, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.2, - "culmen_depth_mm": 15.2, - "flipper_length_mm": 221, - "body_mass_g": 6300, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.2, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 209, - "body_mass_g": 4800, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.7, - "culmen_depth_mm": 15.1, - "flipper_length_mm": 222, - "body_mass_g": 5350, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.2, - "culmen_depth_mm": 14.3, - "flipper_length_mm": 218, - "body_mass_g": 5700, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.1, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 215, - "body_mass_g": 5000, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.5, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 213, - "body_mass_g": 4400, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.3, - "culmen_depth_mm": 15.8, - "flipper_length_mm": 215, - "body_mass_g": 5050, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 42.9, - "culmen_depth_mm": 13.1, - "flipper_length_mm": 215, - "body_mass_g": 5000, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.1, - "culmen_depth_mm": 15.1, - "flipper_length_mm": 215, - "body_mass_g": 5100, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.5, - "culmen_depth_mm": 14.3, - "flipper_length_mm": 216, - "body_mass_g": 4100, - "sex": null - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.8, - "culmen_depth_mm": 15, - "flipper_length_mm": 215, - "body_mass_g": 5650, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.2, - "culmen_depth_mm": 14.3, - "flipper_length_mm": 210, - "body_mass_g": 4600, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50, - "culmen_depth_mm": 15.3, - "flipper_length_mm": 220, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.3, - "culmen_depth_mm": 15.3, - "flipper_length_mm": 222, - "body_mass_g": 5250, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 42.8, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 209, - "body_mass_g": 4700, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.1, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 207, - "body_mass_g": 5050, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 59.6, - "culmen_depth_mm": 17, - "flipper_length_mm": 230, - "body_mass_g": 6050, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.1, - "culmen_depth_mm": 14.8, - "flipper_length_mm": 220, - "body_mass_g": 5150, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.4, - "culmen_depth_mm": 16.3, - "flipper_length_mm": 220, - "body_mass_g": 5400, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 42.6, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 213, - "body_mass_g": 4950, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.4, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 219, - "body_mass_g": 5250, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44, - "culmen_depth_mm": 13.6, - "flipper_length_mm": 208, - "body_mass_g": 4350, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.7, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 208, - "body_mass_g": 5350, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 42.7, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 208, - "body_mass_g": 3950, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.6, - "culmen_depth_mm": 16, - "flipper_length_mm": 225, - "body_mass_g": 5700, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.3, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 210, - "body_mass_g": 4300, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.6, - "culmen_depth_mm": 15, - "flipper_length_mm": 216, - "body_mass_g": 4750, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.5, - "culmen_depth_mm": 15.9, - "flipper_length_mm": 222, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.6, - "culmen_depth_mm": 13.9, - "flipper_length_mm": 217, - "body_mass_g": 4900, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.5, - "culmen_depth_mm": 13.9, - "flipper_length_mm": 210, - "body_mass_g": 4200, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.5, - "culmen_depth_mm": 15.9, - "flipper_length_mm": 225, - "body_mass_g": 5400, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.9, - "culmen_depth_mm": 13.3, - "flipper_length_mm": 213, - "body_mass_g": 5100, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 15.8, - "flipper_length_mm": 215, - "body_mass_g": 5300, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.6, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 210, - "body_mass_g": 4850, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.5, - "culmen_depth_mm": 14.1, - "flipper_length_mm": 220, - "body_mass_g": 5300, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.1, - "culmen_depth_mm": 14.4, - "flipper_length_mm": 210, - "body_mass_g": 4400, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.1, - "culmen_depth_mm": 15, - "flipper_length_mm": 225, - "body_mass_g": 5000, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.5, - "culmen_depth_mm": 14.4, - "flipper_length_mm": 217, - "body_mass_g": 4900, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45, - "culmen_depth_mm": 15.4, - "flipper_length_mm": 220, - "body_mass_g": 5050, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.8, - "culmen_depth_mm": 13.9, - "flipper_length_mm": 208, - "body_mass_g": 4300, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.5, - "culmen_depth_mm": 15, - "flipper_length_mm": 220, - "body_mass_g": 5000, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.2, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 208, - "body_mass_g": 4450, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.4, - "culmen_depth_mm": 15.3, - "flipper_length_mm": 224, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.3, - "culmen_depth_mm": 13.8, - "flipper_length_mm": 208, - "body_mass_g": 4200, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.2, - "culmen_depth_mm": 14.9, - "flipper_length_mm": 221, - "body_mass_g": 5300, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.7, - "culmen_depth_mm": 13.9, - "flipper_length_mm": 214, - "body_mass_g": 4400, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 54.3, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 231, - "body_mass_g": 5650, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.8, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 219, - "body_mass_g": 4700, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.8, - "culmen_depth_mm": 16.8, - "flipper_length_mm": 230, - "body_mass_g": 5700, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.2, - "culmen_depth_mm": 14.4, - "flipper_length_mm": 214, - "body_mass_g": 4650, - "sex": null - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.5, - "culmen_depth_mm": 16.2, - "flipper_length_mm": 229, - "body_mass_g": 5800, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.5, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 220, - "body_mass_g": 4700, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.7, - "culmen_depth_mm": 15, - "flipper_length_mm": 223, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.7, - "culmen_depth_mm": 15, - "flipper_length_mm": 216, - "body_mass_g": 4750, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.4, - "culmen_depth_mm": 15.6, - "flipper_length_mm": 221, - "body_mass_g": 5000, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.2, - "culmen_depth_mm": 15.6, - "flipper_length_mm": 221, - "body_mass_g": 5100, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.5, - "culmen_depth_mm": 14.8, - "flipper_length_mm": 217, - "body_mass_g": 5200, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.4, - "culmen_depth_mm": 15, - "flipper_length_mm": 216, - "body_mass_g": 4700, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.6, - "culmen_depth_mm": 16, - "flipper_length_mm": 230, - "body_mass_g": 5800, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.5, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 209, - "body_mass_g": 4600, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 51.1, - "culmen_depth_mm": 16.3, - "flipper_length_mm": 220, - "body_mass_g": 6000, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 13.8, - "flipper_length_mm": 215, - "body_mass_g": 4750, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 16.4, - "flipper_length_mm": 223, - "body_mass_g": 5950, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.1, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 212, - "body_mass_g": 4625, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 52.5, - "culmen_depth_mm": 15.6, - "flipper_length_mm": 221, - "body_mass_g": 5450, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.4, - "culmen_depth_mm": 14.6, - "flipper_length_mm": 212, - "body_mass_g": 4725, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50, - "culmen_depth_mm": 15.9, - "flipper_length_mm": 224, - "body_mass_g": 5350, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.9, - "culmen_depth_mm": 13.8, - "flipper_length_mm": 212, - "body_mass_g": 4750, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.8, - "culmen_depth_mm": 17.3, - "flipper_length_mm": 228, - "body_mass_g": 5600, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.4, - "culmen_depth_mm": 14.4, - "flipper_length_mm": 218, - "body_mass_g": 4600, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 51.3, - "culmen_depth_mm": 14.2, - "flipper_length_mm": 218, - "body_mass_g": 5300, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.5, - "culmen_depth_mm": 14, - "flipper_length_mm": 212, - "body_mass_g": 4875, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 52.1, - "culmen_depth_mm": 17, - "flipper_length_mm": 230, - "body_mass_g": 5550, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.5, - "culmen_depth_mm": 15, - "flipper_length_mm": 218, - "body_mass_g": 4950, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 52.2, - "culmen_depth_mm": 17.1, - "flipper_length_mm": 228, - "body_mass_g": 5400, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.5, - "culmen_depth_mm": 14.5, - "flipper_length_mm": 212, - "body_mass_g": 4750, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.5, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 224, - "body_mass_g": 5650, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.5, - "culmen_depth_mm": 14.7, - "flipper_length_mm": 214, - "body_mass_g": 4850, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.8, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 226, - "body_mass_g": 5200, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.4, - "culmen_depth_mm": 15.8, - "flipper_length_mm": 216, - "body_mass_g": 4925, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.9, - "culmen_depth_mm": 14.6, - "flipper_length_mm": 222, - "body_mass_g": 4875, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.4, - "culmen_depth_mm": 14.4, - "flipper_length_mm": 203, - "body_mass_g": 4625, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 51.1, - "culmen_depth_mm": 16.5, - "flipper_length_mm": 225, - "body_mass_g": 5250, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.5, - "culmen_depth_mm": 15, - "flipper_length_mm": 219, - "body_mass_g": 4850, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 55.9, - "culmen_depth_mm": 17, - "flipper_length_mm": 228, - "body_mass_g": 5600, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.2, - "culmen_depth_mm": 15.5, - "flipper_length_mm": 215, - "body_mass_g": 4975, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.1, - "culmen_depth_mm": 15, - "flipper_length_mm": 228, - "body_mass_g": 5500, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.3, - "culmen_depth_mm": 13.8, - "flipper_length_mm": 216, - "body_mass_g": 4725, - "sex": null - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.8, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 215, - "body_mass_g": 5500, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 41.7, - "culmen_depth_mm": 14.7, - "flipper_length_mm": 210, - "body_mass_g": 4700, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 53.4, - "culmen_depth_mm": 15.8, - "flipper_length_mm": 219, - "body_mass_g": 5500, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.3, - "culmen_depth_mm": 14, - "flipper_length_mm": 208, - "body_mass_g": 4575, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.1, - "culmen_depth_mm": 15.1, - "flipper_length_mm": 209, - "body_mass_g": 5500, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.5, - "culmen_depth_mm": 15.2, - "flipper_length_mm": 216, - "body_mass_g": 5000, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.8, - "culmen_depth_mm": 15.9, - "flipper_length_mm": 229, - "body_mass_g": 5950, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 43.5, - "culmen_depth_mm": 15.2, - "flipper_length_mm": 213, - "body_mass_g": 4650, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 51.5, - "culmen_depth_mm": 16.3, - "flipper_length_mm": 230, - "body_mass_g": 5500, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.2, - "culmen_depth_mm": 14.1, - "flipper_length_mm": 217, - "body_mass_g": 4375, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 55.1, - "culmen_depth_mm": 16, - "flipper_length_mm": 230, - "body_mass_g": 5850, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 44.5, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 217, - "body_mass_g": 4875, - "sex": null - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 48.8, - "culmen_depth_mm": 16.2, - "flipper_length_mm": 222, - "body_mass_g": 6000, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 47.2, - "culmen_depth_mm": 13.7, - "flipper_length_mm": 214, - "body_mass_g": 4925, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": null, - "culmen_depth_mm": null, - "flipper_length_mm": null, - "body_mass_g": null, - "sex": null - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 46.8, - "culmen_depth_mm": 14.3, - "flipper_length_mm": 215, - "body_mass_g": 4850, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 50.4, - "culmen_depth_mm": 15.7, - "flipper_length_mm": 222, - "body_mass_g": 5750, - "sex": "MALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 45.2, - "culmen_depth_mm": 14.8, - "flipper_length_mm": 212, - "body_mass_g": 5200, - "sex": "FEMALE" - }, - { - "species": "Gentoo", - "island": "Biscoe", - "culmen_length_mm": 49.9, - "culmen_depth_mm": 16.1, - "flipper_length_mm": 213, - "body_mass_g": 5400, - "sex": "MALE" - } -] diff --git a/src/plugins/d3/__stories__/pie/Basic.stories.tsx b/src/plugins/d3/__stories__/pie/Basic.stories.tsx deleted file mode 100644 index fd62ce38..00000000 --- a/src/plugins/d3/__stories__/pie/Basic.stories.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import {BasicPie} from '../../examples/pie/Basic'; -import {Donut} from '../../examples/pie/Donut'; -import {DonutWithTotals} from '../../examples/pie/DonutWithTotals'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BasicPieStory: StoryObj = { - name: 'Basic pie', - args: { - Chart: BasicPie, - }, -}; - -export const BasicDonutStory: StoryObj = { - name: 'Basic donut', - args: { - Chart: Donut, - }, -}; - -export const DonutWithTotalsStory: StoryObj = { - name: 'Donut with totals', - args: { - Chart: DonutWithTotals, - }, -}; - -export default { - title: 'Plugins/D3/Pie', - decorators: [withKnobs], - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/pie/ContinuousLegend.stories.tsx b/src/plugins/d3/__stories__/pie/ContinuousLegend.stories.tsx deleted file mode 100644 index 32fcdec6..00000000 --- a/src/plugins/d3/__stories__/pie/ContinuousLegend.stories.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; - -import type {StoryObj} from '@storybook/react'; -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData, PieSeriesData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import nintendoGames from '../../examples/nintendoGames'; -import {D3Plugin} from '../../index'; -import {getContinuesColorFn} from '../../renderer/utils'; - -const PieWithContinuousLegend = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const colors = ['rgb(255, 61, 100)', 'rgb(255, 198, 54)', 'rgb(84, 165, 32)']; - const stops = [0, 0.5, 1]; - - const gamesByPlatform = groups(nintendoGames, (item) => item.platform); - const data: PieSeriesData[] = gamesByPlatform.map(([platform, games]) => ({ - name: platform, - value: games.length, - label: `${platform}(${games.length})`, - })); - const getColor = getContinuesColorFn({colors, stops, values: data.map((d) => d.value)}); - data.forEach((d) => { - d.color = getColor(d.value); - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'pie', - data, - }, - ], - }, - title: {text: 'Pie with continues color'}, - legend: { - enabled: true, - type: 'continuous', - title: {text: 'Games by platform'}, - colorScale: { - colors: colors, - stops, - }, - }, - }; - - return ( - - - - ); -}; - -export const PieWithContinuousLegendStory: StoryObj = { - name: 'Pie with continuous color', -}; - -export default { - title: 'Plugins/D3/Pie', - component: PieWithContinuousLegend, -}; diff --git a/src/plugins/d3/__stories__/pie/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/pie/HtmlLabels.stories.tsx deleted file mode 100644 index 669658d0..00000000 --- a/src/plugins/d3/__stories__/pie/HtmlLabels.stories.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const PieWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const getPieSegmentData = (name: string, color: string) => { - const labelStyle = `background: ${color};color: #fff;padding: 4px;border-radius: 4px;`; - return { - name: name, - value: Math.random() * 10, - label: `${name}`, - color: color, - }; - }; - - const getWidgetData = (): ChartKitWidgetData => ({ - series: { - data: [ - { - type: 'pie', - dataLabels: { - enabled: true, - html: true, - connectorPadding: 8, - }, - data: [ - getPieSegmentData('One', '#4fc4b7'), - getPieSegmentData('Two', '#59abc9'), - getPieSegmentData('Three', '#8ccce3'), - ], - }, - ], - }, - title: {text: 'Pie with html labels'}, - legend: {enabled: true}, - }); - - return ( - - - - - - - - - - ); -}; - -export const PieWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Pie', - component: PieWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/pie/Playground.stories.tsx b/src/plugins/d3/__stories__/pie/Playground.stories.tsx deleted file mode 100644 index 556e5718..00000000 --- a/src/plugins/d3/__stories__/pie/Playground.stories.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {descending, groups, sort} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; -import {HighchartsPlugin} from '../../../highcharts'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData(): ChartKitWidgetData { - const gamesByPlatform = groups(nintendoGames, (item) => item.platform); - const seriesData = gamesByPlatform.map(([platform, games]) => ({ - name: platform, - value: games.length, - label: `${platform} (${games.length})`, - })); - - return { - series: { - data: [ - { - type: 'pie', - data: sort(seriesData, (d1, d2) => descending(d1.value, d2.value)), - dataLabels: { - enabled: true, - connectorCurve: 'basic', - }, - }, - ], - }, - legend: {enabled: true}, - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin, HighchartsPlugin]}); - return ; - } - - return ( - <> -
- -
-
- ({ - ...d, - y: d.value, - })), - }, - ], - }, - config: {}, - libraryConfig: { - title: {text: 'Highcharts'}, - legend: {enabled: true}, - }, - }} - /> -
- - ); -}; - -export const PlaygroundPieChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Pie', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/pie/Styled.stories.tsx b/src/plugins/d3/__stories__/pie/Styled.stories.tsx deleted file mode 100644 index 234c1469..00000000 --- a/src/plugins/d3/__stories__/pie/Styled.stories.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {object, withKnobs} from '@storybook/addon-knobs'; -import {Meta, Story} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData} from '../../../../types'; - -const Template: Story = () => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - const data: ChartKitWidgetData = { - series: { - data: [ - { - type: 'pie', - borderRadius: 5, - borderWidth: 3, - center: ['25%', null], - radius: '75%', - dataLabels: {enabled: false}, - data: [ - { - name: 'One 1', - value: 50, - }, - { - name: 'Two 1', - value: 20, - }, - { - name: 'Three 1', - value: 90, - }, - ], - }, - { - type: 'pie', - borderRadius: 5, - borderWidth: 3, - center: ['75%', null], - innerRadius: '50%', - radius: '75%', - dataLabels: {enabled: false}, - data: [ - { - name: 'One 2', - value: 50, - }, - { - name: 'Two 2', - value: 20, - }, - { - name: 'Three 2', - value: 90, - }, - ], - }, - ], - }, - title: {text: 'Styled pies'}, - legend: {enabled: false}, - tooltip: {enabled: true}, - }; - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- ('data', data)} /> -
- ); -}; - -export const Styled = Template.bind({}); - -const meta: Meta = { - title: 'Plugins/D3/Pie', - decorators: [withKnobs], -}; - -export default meta; diff --git a/src/plugins/d3/__stories__/scatter-performance.json b/src/plugins/d3/__stories__/scatter-performance.json deleted file mode 100644 index 85d77af7..00000000 --- a/src/plugins/d3/__stories__/scatter-performance.json +++ /dev/null @@ -1,36686 +0,0 @@ -{ - "series": { - "data": [ - { - "type": "scatter", - "name": "", - "color": "#4DA2F1", - "data": [ - { - "custom": { - "xLabel": "Faaa", - "yLabel": "25 888" - }, - "category": "Faaa", - "y": 25888 - }, - { - "custom": { - "xLabel": "Corumbá", - "yLabel": "90 111" - }, - "category": "Corumbá", - "y": 90111 - }, - { - "custom": { - "xLabel": "Zhenjiang", - "yLabel": "368 316" - }, - "category": "Zhenjiang", - "y": 368316 - }, - { - "custom": { - "xLabel": "Hafar al-Batin", - "yLabel": "137 800" - }, - "category": "Hafar al-Batin", - "y": 137800 - }, - { - "custom": { - "xLabel": "Abadan", - "yLabel": "206 073" - }, - "category": "Abadan", - "y": 206073 - }, - { - "custom": { - "xLabel": "Khouribga", - "yLabel": "152 090" - }, - "category": "Khouribga", - "y": 152090 - }, - { - "custom": { - "xLabel": "Odesa", - "yLabel": "1 011 000" - }, - "category": "Odesa", - "y": 1011000 - }, - { - "custom": { - "xLabel": "Amol", - "yLabel": "159 092" - }, - "category": "Amol", - "y": 159092 - }, - { - "custom": { - "xLabel": "Victoria", - "yLabel": "1 312 637" - }, - "category": "Victoria", - "y": 1312637 - }, - { - "custom": { - "xLabel": "Negombo", - "yLabel": "100 000" - }, - "category": "Negombo", - "y": 100000 - }, - { - "custom": { - "xLabel": "Prato", - "yLabel": "172 473" - }, - "category": "Prato", - "y": 172473 - }, - { - "custom": { - "xLabel": "Zielona Góra", - "yLabel": "118 182" - }, - "category": "Zielona Góra", - "y": 118182 - }, - { - "custom": { - "xLabel": "Qujing", - "yLabel": "178 669" - }, - "category": "Qujing", - "y": 178669 - }, - { - "custom": { - "xLabel": "Tianmen", - "yLabel": "186 332" - }, - "category": "Tianmen", - "y": 186332 - }, - { - "custom": { - "xLabel": "Syzran", - "yLabel": "186 900" - }, - "category": "Syzran", - "y": 186900 - }, - { - "custom": { - "xLabel": "Toluca", - "yLabel": "665 617" - }, - "category": "Toluca", - "y": 665617 - }, - { - "custom": { - "xLabel": "Franca", - "yLabel": "290 139" - }, - "category": "Franca", - "y": 290139 - }, - { - "custom": { - "xLabel": "Colchester", - "yLabel": "96 063" - }, - "category": "Colchester", - "y": 96063 - }, - { - "custom": { - "xLabel": "Linfen", - "yLabel": "187 309" - }, - "category": "Linfen", - "y": 187309 - }, - { - "custom": { - "xLabel": "Sfax", - "yLabel": "257 800" - }, - "category": "Sfax", - "y": 257800 - }, - { - "custom": { - "xLabel": "Magdeburg", - "yLabel": "235 073" - }, - "category": "Magdeburg", - "y": 235073 - }, - { - "custom": { - "xLabel": "Nandyal", - "yLabel": "119 813" - }, - "category": "Nandyal", - "y": 119813 - }, - { - "custom": { - "xLabel": "Tecámac", - "yLabel": "172 410" - }, - "category": "Tecámac", - "y": 172410 - }, - { - "custom": { - "xLabel": "Udine", - "yLabel": "94 932" - }, - "category": "Udine", - "y": 94932 - }, - { - "custom": { - "xLabel": "Guwahati (Gauhati)", - "yLabel": "584 342" - }, - "category": "Guwahati (Gauhati)", - "y": 584342 - }, - { - "custom": { - "xLabel": "Dniprodzerzynsk", - "yLabel": "270 000" - }, - "category": "Dniprodzerzynsk", - "y": 270000 - }, - { - "custom": { - "xLabel": "Philadelphia", - "yLabel": "1 517 550" - }, - "category": "Philadelphia", - "y": 1517550 - }, - { - "custom": { - "xLabel": "Junagadh", - "yLabel": "130 484" - }, - "category": "Junagadh", - "y": 130484 - }, - { - "custom": { - "xLabel": "Gingoog", - "yLabel": "102 379" - }, - "category": "Gingoog", - "y": 102379 - }, - { - "custom": { - "xLabel": "Kaduna", - "yLabel": "342 200" - }, - "category": "Kaduna", - "y": 342200 - }, - { - "custom": { - "xLabel": "Liepaja", - "yLabel": "89 439" - }, - "category": "Liepaja", - "y": 89439 - }, - { - "custom": { - "xLabel": "Surakarta", - "yLabel": "518 600" - }, - "category": "Surakarta", - "y": 518600 - }, - { - "custom": { - "xLabel": "Sirjan", - "yLabel": "135 024" - }, - "category": "Sirjan", - "y": 135024 - }, - { - "custom": { - "xLabel": "Ciudad Ojeda", - "yLabel": "99 354" - }, - "category": "Ciudad Ojeda", - "y": 99354 - }, - { - "custom": { - "xLabel": "Fort Wayne", - "yLabel": "205 727" - }, - "category": "Fort Wayne", - "y": 205727 - }, - { - "custom": { - "xLabel": "Moulmein (Mawlamyine)", - "yLabel": "307 900" - }, - "category": "Moulmein (Mawlamyine)", - "y": 307900 - }, - { - "custom": { - "xLabel": "Jinhua", - "yLabel": "144 280" - }, - "category": "Jinhua", - "y": 144280 - }, - { - "custom": { - "xLabel": "Oita", - "yLabel": "433 401" - }, - "category": "Oita", - "y": 433401 - }, - { - "custom": { - "xLabel": "Kawaguchi", - "yLabel": "452 155" - }, - "category": "Kawaguchi", - "y": 452155 - }, - { - "custom": { - "xLabel": "Moshi", - "yLabel": "96 800" - }, - "category": "Moshi", - "y": 96800 - }, - { - "custom": { - "xLabel": "Ríobamba", - "yLabel": "123 163" - }, - "category": "Ríobamba", - "y": 123163 - }, - { - "custom": { - "xLabel": "Baltimore", - "yLabel": "651 154" - }, - "category": "Baltimore", - "y": 651154 - }, - { - "custom": { - "xLabel": "Buzau", - "yLabel": "148 372" - }, - "category": "Buzau", - "y": 148372 - }, - { - "custom": { - "xLabel": "Sagamihara", - "yLabel": "586 300" - }, - "category": "Sagamihara", - "y": 586300 - }, - { - "custom": { - "xLabel": "Uijongbu", - "yLabel": "276 111" - }, - "category": "Uijongbu", - "y": 276111 - }, - { - "custom": { - "xLabel": "Alexandria", - "yLabel": "3 328 196" - }, - "category": "Alexandria", - "y": 3328196 - }, - { - "custom": { - "xLabel": "Bialystok", - "yLabel": "283 937" - }, - "category": "Bialystok", - "y": 283937 - }, - { - "custom": { - "xLabel": "Almetjevsk", - "yLabel": "140 700" - }, - "category": "Almetjevsk", - "y": 140700 - }, - { - "custom": { - "xLabel": "Sangli", - "yLabel": "193 197" - }, - "category": "Sangli", - "y": 193197 - }, - { - "custom": { - "xLabel": "Zoetermeer", - "yLabel": "110 214" - }, - "category": "Zoetermeer", - "y": 110214 - }, - { - "custom": { - "xLabel": "Krementšuk", - "yLabel": "239 000" - }, - "category": "Krementšuk", - "y": 239000 - }, - { - "custom": { - "xLabel": "Düren", - "yLabel": "91 092" - }, - "category": "Düren", - "y": 91092 - }, - { - "custom": { - "xLabel": "San Pablo", - "yLabel": "207 927" - }, - "category": "San Pablo", - "y": 207927 - }, - { - "custom": { - "xLabel": "Amersfoort", - "yLabel": "126 270" - }, - "category": "Amersfoort", - "y": 126270 - }, - { - "custom": { - "xLabel": "Qashqar", - "yLabel": "174 570" - }, - "category": "Qashqar", - "y": 174570 - }, - { - "custom": { - "xLabel": "Elista", - "yLabel": "103 300" - }, - "category": "Elista", - "y": 103300 - }, - { - "custom": { - "xLabel": "La Spezia", - "yLabel": "95 504" - }, - "category": "La Spezia", - "y": 95504 - }, - { - "custom": { - "xLabel": "Mixco", - "yLabel": "209 791" - }, - "category": "Mixco", - "y": 209791 - }, - { - "custom": { - "xLabel": "Bahawalpur", - "yLabel": "403 408" - }, - "category": "Bahawalpur", - "y": 403408 - }, - { - "custom": { - "xLabel": "Qostanay", - "yLabel": "221 400" - }, - "category": "Qostanay", - "y": 221400 - }, - { - "custom": { - "xLabel": "Kolpino", - "yLabel": "141 200" - }, - "category": "Kolpino", - "y": 141200 - }, - { - "custom": { - "xLabel": "Wuhu", - "yLabel": "425 740" - }, - "category": "Wuhu", - "y": 425740 - }, - { - "custom": { - "xLabel": "Pitesti", - "yLabel": "187 170" - }, - "category": "Pitesti", - "y": 187170 - }, - { - "custom": { - "xLabel": "Anápolis", - "yLabel": "282 197" - }, - "category": "Anápolis", - "y": 282197 - }, - { - "custom": { - "xLabel": "Essen", - "yLabel": "599 515" - }, - "category": "Essen", - "y": 599515 - }, - { - "custom": { - "xLabel": "Chunchon", - "yLabel": "234 528" - }, - "category": "Chunchon", - "y": 234528 - }, - { - "custom": { - "xLabel": "Cianjur", - "yLabel": "114 300" - }, - "category": "Cianjur", - "y": 114300 - }, - { - "custom": { - "xLabel": "Bahraich", - "yLabel": "135 400" - }, - "category": "Bahraich", - "y": 135400 - }, - { - "custom": { - "xLabel": "Kediri", - "yLabel": "253 760" - }, - "category": "Kediri", - "y": 253760 - }, - { - "custom": { - "xLabel": "Panzhihua", - "yLabel": "415 466" - }, - "category": "Panzhihua", - "y": 415466 - }, - { - "custom": { - "xLabel": "Hradec Králové", - "yLabel": "98 080" - }, - "category": "Hradec Králové", - "y": 98080 - }, - { - "custom": { - "xLabel": "Petaling Jaya", - "yLabel": "254 350" - }, - "category": "Petaling Jaya", - "y": 254350 - }, - { - "custom": { - "xLabel": "Fall River", - "yLabel": "90 555" - }, - "category": "Fall River", - "y": 90555 - }, - { - "custom": { - "xLabel": "Albuquerque", - "yLabel": "448 607" - }, - "category": "Albuquerque", - "y": 448607 - }, - { - "custom": { - "xLabel": "Puchon", - "yLabel": "779 412" - }, - "category": "Puchon", - "y": 779412 - }, - { - "custom": { - "xLabel": "Kasugai", - "yLabel": "282 348" - }, - "category": "Kasugai", - "y": 282348 - }, - { - "custom": { - "xLabel": "Almirante Brown", - "yLabel": "538 918" - }, - "category": "Almirante Brown", - "y": 538918 - }, - { - "custom": { - "xLabel": "Aurora", - "yLabel": "142 990" - }, - "category": "Aurora", - "y": 142990 - }, - { - "custom": { - "xLabel": "Vanadzor", - "yLabel": "172 700" - }, - "category": "Vanadzor", - "y": 172700 - }, - { - "custom": { - "xLabel": "Suzhou", - "yLabel": "151 862" - }, - "category": "Suzhou", - "y": 151862 - }, - { - "custom": { - "xLabel": "Tšerkessk", - "yLabel": "121 700" - }, - "category": "Tšerkessk", - "y": 121700 - }, - { - "custom": { - "xLabel": "Atlixco", - "yLabel": "117 019" - }, - "category": "Atlixco", - "y": 117019 - }, - { - "custom": { - "xLabel": "Omuta", - "yLabel": "142 889" - }, - "category": "Omuta", - "y": 142889 - }, - { - "custom": { - "xLabel": "Townsville", - "yLabel": "109 914" - }, - "category": "Townsville", - "y": 109914 - }, - { - "custom": { - "xLabel": "Avarua", - "yLabel": "11 900" - }, - "category": "Avarua", - "y": 11900 - }, - { - "custom": { - "xLabel": "Jakarta", - "yLabel": "9 604 900" - }, - "category": "Jakarta", - "y": 9604900 - }, - { - "custom": { - "xLabel": "Passos", - "yLabel": "98 570" - }, - "category": "Passos", - "y": 98570 - }, - { - "custom": { - "xLabel": "Buhoro", - "yLabel": "237 100" - }, - "category": "Buhoro", - "y": 237100 - }, - { - "custom": { - "xLabel": "Santa Maria", - "yLabel": "238 473" - }, - "category": "Santa Maria", - "y": 238473 - }, - { - "custom": { - "xLabel": "Mogadishu", - "yLabel": "997 000" - }, - "category": "Mogadishu", - "y": 997000 - }, - { - "custom": { - "xLabel": "La Habana", - "yLabel": "2 256 000" - }, - "category": "La Habana", - "y": 2256000 - }, - { - "custom": { - "xLabel": "Dongying", - "yLabel": "281 728" - }, - "category": "Dongying", - "y": 281728 - }, - { - "custom": { - "xLabel": "Tonalá", - "yLabel": "336 109" - }, - "category": "Tonalá", - "y": 336109 - }, - { - "custom": { - "xLabel": "Petrópolis", - "yLabel": "279 183" - }, - "category": "Petrópolis", - "y": 279183 - }, - { - "custom": { - "xLabel": "Jahrom", - "yLabel": "94 200" - }, - "category": "Jahrom", - "y": 94200 - }, - { - "custom": { - "xLabel": "Solihull", - "yLabel": "94 531" - }, - "category": "Solihull", - "y": 94531 - }, - { - "custom": { - "xLabel": "Bene Beraq", - "yLabel": "133 900" - }, - "category": "Bene Beraq", - "y": 133900 - }, - { - "custom": { - "xLabel": "Krasnojarsk", - "yLabel": "875 500" - }, - "category": "Krasnojarsk", - "y": 875500 - }, - { - "custom": { - "xLabel": "Gurue", - "yLabel": "99 300" - }, - "category": "Gurue", - "y": 99300 - }, - { - "custom": { - "xLabel": "Renqiu", - "yLabel": "114 256" - }, - "category": "Renqiu", - "y": 114256 - }, - { - "custom": { - "xLabel": "Chinandega", - "yLabel": "97 387" - }, - "category": "Chinandega", - "y": 97387 - }, - { - "custom": { - "xLabel": "Lublin", - "yLabel": "356 251" - }, - "category": "Lublin", - "y": 356251 - }, - { - "custom": { - "xLabel": "Tempe", - "yLabel": "158 625" - }, - "category": "Tempe", - "y": 158625 - }, - { - "custom": { - "xLabel": "Borås", - "yLabel": "96 883" - }, - "category": "Borås", - "y": 96883 - }, - { - "custom": { - "xLabel": "Tilburg", - "yLabel": "193 238" - }, - "category": "Tilburg", - "y": 193238 - }, - { - "custom": { - "xLabel": "Boston", - "yLabel": "589 141" - }, - "category": "Boston", - "y": 589141 - }, - { - "custom": { - "xLabel": "Shangzi", - "yLabel": "215 373" - }, - "category": "Shangzi", - "y": 215373 - }, - { - "custom": { - "xLabel": "Nonthaburi", - "yLabel": "292 100" - }, - "category": "Nonthaburi", - "y": 292100 - }, - { - "custom": { - "xLabel": "Changji", - "yLabel": "132 260" - }, - "category": "Changji", - "y": 132260 - }, - { - "custom": { - "xLabel": "Evansville", - "yLabel": "121 582" - }, - "category": "Evansville", - "y": 121582 - }, - { - "custom": { - "xLabel": "Cienfuegos", - "yLabel": "132 770" - }, - "category": "Cienfuegos", - "y": 132770 - }, - { - "custom": { - "xLabel": "Ujjain", - "yLabel": "362 266" - }, - "category": "Ujjain", - "y": 362266 - }, - { - "custom": { - "xLabel": "Bhubaneswar", - "yLabel": "411 542" - }, - "category": "Bhubaneswar", - "y": 411542 - }, - { - "custom": { - "xLabel": "Nagano", - "yLabel": "361 391" - }, - "category": "Nagano", - "y": 361391 - }, - { - "custom": { - "xLabel": "Vinh", - "yLabel": "112 455" - }, - "category": "Vinh", - "y": 112455 - }, - { - "custom": { - "xLabel": "Timisoara", - "yLabel": "324 304" - }, - "category": "Timisoara", - "y": 324304 - }, - { - "custom": { - "xLabel": "San Fernando del Valle de Cata", - "yLabel": "134 935" - }, - "category": "San Fernando del Valle de Cata", - "y": 134935 - }, - { - "custom": { - "xLabel": "Chiclayo", - "yLabel": "517 000" - }, - "category": "Chiclayo", - "y": 517000 - }, - { - "custom": { - "xLabel": "Guaíba", - "yLabel": "92 224" - }, - "category": "Guaíba", - "y": 92224 - }, - { - "custom": { - "xLabel": "Poços de Caldas", - "yLabel": "129 683" - }, - "category": "Poços de Caldas", - "y": 129683 - }, - { - "custom": { - "xLabel": "San Diego", - "yLabel": "1 223 400" - }, - "category": "San Diego", - "y": 1223400 - }, - { - "custom": { - "xLabel": "Preston", - "yLabel": "135 000" - }, - "category": "Preston", - "y": 135000 - }, - { - "custom": { - "xLabel": "Haldwani-cum-Kathgodam", - "yLabel": "104 195" - }, - "category": "Haldwani-cum-Kathgodam", - "y": 104195 - }, - { - "custom": { - "xLabel": "Lagos", - "yLabel": "1 518 000" - }, - "category": "Lagos", - "y": 1518000 - }, - { - "custom": { - "xLabel": "Brugge", - "yLabel": "116 246" - }, - "category": "Brugge", - "y": 116246 - }, - { - "custom": { - "xLabel": "Stavanger", - "yLabel": "108 848" - }, - "category": "Stavanger", - "y": 108848 - }, - { - "custom": { - "xLabel": "Maracaíbo", - "yLabel": "1 304 776" - }, - "category": "Maracaíbo", - "y": 1304776 - }, - { - "custom": { - "xLabel": "Aba", - "yLabel": "298 900" - }, - "category": "Aba", - "y": 298900 - }, - { - "custom": { - "xLabel": "Niihama", - "yLabel": "127 207" - }, - "category": "Niihama", - "y": 127207 - }, - { - "custom": { - "xLabel": "Torino", - "yLabel": "903 705" - }, - "category": "Torino", - "y": 903705 - }, - { - "custom": { - "xLabel": "Haarlemmermeer", - "yLabel": "110 722" - }, - "category": "Haarlemmermeer", - "y": 110722 - }, - { - "custom": { - "xLabel": "Vancouver", - "yLabel": "143 560" - }, - "category": "Vancouver", - "y": 143560 - }, - { - "custom": { - "xLabel": "Ceské Budejovice", - "yLabel": "98 186" - }, - "category": "Ceské Budejovice", - "y": 98186 - }, - { - "custom": { - "xLabel": "Midnapore (Medinipur)", - "yLabel": "125 498" - }, - "category": "Midnapore (Medinipur)", - "y": 125498 - }, - { - "custom": { - "xLabel": "Exeter", - "yLabel": "111 000" - }, - "category": "Exeter", - "y": 111000 - }, - { - "custom": { - "xLabel": "Talavera", - "yLabel": "97 329" - }, - "category": "Talavera", - "y": 97329 - }, - { - "custom": { - "xLabel": "Novomoskovsk", - "yLabel": "138 100" - }, - "category": "Novomoskovsk", - "y": 138100 - }, - { - "custom": { - "xLabel": "North Barrackpur", - "yLabel": "100 513" - }, - "category": "North Barrackpur", - "y": 100513 - }, - { - "custom": { - "xLabel": "Šostka", - "yLabel": "90 000" - }, - "category": "Šostka", - "y": 90000 - }, - { - "custom": { - "xLabel": "Navojoa", - "yLabel": "140 495" - }, - "category": "Navojoa", - "y": 140495 - }, - { - "custom": { - "xLabel": "San Jose", - "yLabel": "894 943" - }, - "category": "San Jose", - "y": 894943 - }, - { - "custom": { - "xLabel": "Zaria", - "yLabel": "379 200" - }, - "category": "Zaria", - "y": 379200 - }, - { - "custom": { - "xLabel": "Marand", - "yLabel": "96 400" - }, - "category": "Marand", - "y": 96400 - }, - { - "custom": { - "xLabel": "Bergen", - "yLabel": "230 948" - }, - "category": "Bergen", - "y": 230948 - }, - { - "custom": { - "xLabel": "Košice", - "yLabel": "241 874" - }, - "category": "Košice", - "y": 241874 - }, - { - "custom": { - "xLabel": "Comitán de Domínguez", - "yLabel": "104 986" - }, - "category": "Comitán de Domínguez", - "y": 104986 - }, - { - "custom": { - "xLabel": "Chongju", - "yLabel": "531 376" - }, - "category": "Chongju", - "y": 531376 - }, - { - "custom": { - "xLabel": "Duisburg", - "yLabel": "519 793" - }, - "category": "Duisburg", - "y": 519793 - }, - { - "custom": { - "xLabel": "Xai-Xai", - "yLabel": "99 442" - }, - "category": "Xai-Xai", - "y": 99442 - }, - { - "custom": { - "xLabel": "Ibadan", - "yLabel": "1 432 000" - }, - "category": "Ibadan", - "y": 1432000 - }, - { - "custom": { - "xLabel": "Manizales", - "yLabel": "337 580" - }, - "category": "Manizales", - "y": 337580 - }, - { - "custom": { - "xLabel": "Hims", - "yLabel": "507 404" - }, - "category": "Hims", - "y": 507404 - }, - { - "custom": { - "xLabel": "Gorakhpur", - "yLabel": "505 566" - }, - "category": "Gorakhpur", - "y": 505566 - }, - { - "custom": { - "xLabel": "Johor Baharu", - "yLabel": "328 436" - }, - "category": "Johor Baharu", - "y": 328436 - }, - { - "custom": { - "xLabel": "Alessandria", - "yLabel": "90 289" - }, - "category": "Alessandria", - "y": 90289 - }, - { - "custom": { - "xLabel": "Helsinki [Helsingfors]", - "yLabel": "555 474" - }, - "category": "Helsinki [Helsingfors]", - "y": 555474 - }, - { - "custom": { - "xLabel": "Borujerd", - "yLabel": "217 804" - }, - "category": "Borujerd", - "y": 217804 - }, - { - "custom": { - "xLabel": "Trujillo", - "yLabel": "652 000" - }, - "category": "Trujillo", - "y": 652000 - }, - { - "custom": { - "xLabel": "Tbilisi", - "yLabel": "1 235 200" - }, - "category": "Tbilisi", - "y": 1235200 - }, - { - "custom": { - "xLabel": "Yangsan", - "yLabel": "163 351" - }, - "category": "Yangsan", - "y": 163351 - }, - { - "custom": { - "xLabel": "Gómez Palacio", - "yLabel": "272 806" - }, - "category": "Gómez Palacio", - "y": 272806 - }, - { - "custom": { - "xLabel": "Konotop", - "yLabel": "96 000" - }, - "category": "Konotop", - "y": 96000 - }, - { - "custom": { - "xLabel": "Habikino", - "yLabel": "118 968" - }, - "category": "Habikino", - "y": 118968 - }, - { - "custom": { - "xLabel": "Saint Paul", - "yLabel": "287 151" - }, - "category": "Saint Paul", - "y": 287151 - }, - { - "custom": { - "xLabel": "Independence", - "yLabel": "113 288" - }, - "category": "Independence", - "y": 113288 - }, - { - "custom": { - "xLabel": "Zagreb", - "yLabel": "706 770" - }, - "category": "Zagreb", - "y": 706770 - }, - { - "custom": { - "xLabel": "Idlib", - "yLabel": "91 081" - }, - "category": "Idlib", - "y": 91081 - }, - { - "custom": { - "xLabel": "Kalemie", - "yLabel": "101 309" - }, - "category": "Kalemie", - "y": 101309 - }, - { - "custom": { - "xLabel": "Tali", - "yLabel": "171 940" - }, - "category": "Tali", - "y": 171940 - }, - { - "custom": { - "xLabel": "Focsani", - "yLabel": "98 979" - }, - "category": "Focsani", - "y": 98979 - }, - { - "custom": { - "xLabel": "Garland", - "yLabel": "215 768" - }, - "category": "Garland", - "y": 215768 - }, - { - "custom": { - "xLabel": "Bekasi", - "yLabel": "644 300" - }, - "category": "Bekasi", - "y": 644300 - }, - { - "custom": { - "xLabel": "São Vicente", - "yLabel": "286 848" - }, - "category": "São Vicente", - "y": 286848 - }, - { - "custom": { - "xLabel": "Badajoz", - "yLabel": "136 613" - }, - "category": "Badajoz", - "y": 136613 - }, - { - "custom": { - "xLabel": "León", - "yLabel": "1 133 576" - }, - "category": "León", - "y": 1133576 - }, - { - "custom": { - "xLabel": "Takamatsu", - "yLabel": "332 471" - }, - "category": "Takamatsu", - "y": 332471 - }, - { - "custom": { - "xLabel": "Grenoble", - "yLabel": "153 317" - }, - "category": "Grenoble", - "y": 153317 - }, - { - "custom": { - "xLabel": "Ashdod", - "yLabel": "155 800" - }, - "category": "Ashdod", - "y": 155800 - }, - { - "custom": { - "xLabel": "Bacoor", - "yLabel": "305 699" - }, - "category": "Bacoor", - "y": 305699 - }, - { - "custom": { - "xLabel": "Uruapan", - "yLabel": "265 211" - }, - "category": "Uruapan", - "y": 265211 - }, - { - "custom": { - "xLabel": "San Pedro Sula", - "yLabel": "383 900" - }, - "category": "San Pedro Sula", - "y": 383900 - }, - { - "custom": { - "xLabel": "Wad Madani", - "yLabel": "211 362" - }, - "category": "Wad Madani", - "y": 211362 - }, - { - "custom": { - "xLabel": "Inanda", - "yLabel": "634 065" - }, - "category": "Inanda", - "y": 634065 - }, - { - "custom": { - "xLabel": "Tamuning", - "yLabel": "9 500" - }, - "category": "Tamuning", - "y": 9500 - }, - { - "custom": { - "xLabel": "Coacalco de Berriozábal", - "yLabel": "252 270" - }, - "category": "Coacalco de Berriozábal", - "y": 252270 - }, - { - "custom": { - "xLabel": "Capas", - "yLabel": "95 219" - }, - "category": "Capas", - "y": 95219 - }, - { - "custom": { - "xLabel": "Miami", - "yLabel": "362 470" - }, - "category": "Miami", - "y": 362470 - }, - { - "custom": { - "xLabel": "Long Xuyen", - "yLabel": "132 681" - }, - "category": "Long Xuyen", - "y": 132681 - }, - { - "custom": { - "xLabel": "Mexicali", - "yLabel": "764 902" - }, - "category": "Mexicali", - "y": 764902 - }, - { - "custom": { - "xLabel": "Southampton", - "yLabel": "216 000" - }, - "category": "Southampton", - "y": 216000 - }, - { - "custom": { - "xLabel": "João Pessoa", - "yLabel": "584 029" - }, - "category": "João Pessoa", - "y": 584029 - }, - { - "custom": { - "xLabel": "Serekunda", - "yLabel": "102 600" - }, - "category": "Serekunda", - "y": 102600 - }, - { - "custom": { - "xLabel": "Ikire", - "yLabel": "123 300" - }, - "category": "Ikire", - "y": 123300 - }, - { - "custom": { - "xLabel": "Casablanca", - "yLabel": "2 940 623" - }, - "category": "Casablanca", - "y": 2940623 - }, - { - "custom": { - "xLabel": "Kakogawa", - "yLabel": "266 281" - }, - "category": "Kakogawa", - "y": 266281 - }, - { - "custom": { - "xLabel": "Aksaray", - "yLabel": "102 681" - }, - "category": "Aksaray", - "y": 102681 - }, - { - "custom": { - "xLabel": "Grimsby", - "yLabel": "89 000" - }, - "category": "Grimsby", - "y": 89000 - }, - { - "custom": { - "xLabel": "Corona", - "yLabel": "124 966" - }, - "category": "Corona", - "y": 124966 - }, - { - "custom": { - "xLabel": "Kovrov", - "yLabel": "159 900" - }, - "category": "Kovrov", - "y": 159900 - }, - { - "custom": { - "xLabel": "Belgaum", - "yLabel": "326 399" - }, - "category": "Belgaum", - "y": 326399 - }, - { - "custom": { - "xLabel": "Manzanillo", - "yLabel": "124 014" - }, - "category": "Manzanillo", - "y": 124014 - }, - { - "custom": { - "xLabel": "Gujrat", - "yLabel": "250 121" - }, - "category": "Gujrat", - "y": 250121 - }, - { - "custom": { - "xLabel": "Palangka Raya", - "yLabel": "99 693" - }, - "category": "Palangka Raya", - "y": 99693 - }, - { - "custom": { - "xLabel": "Pihkova", - "yLabel": "201 500" - }, - "category": "Pihkova", - "y": 201500 - }, - { - "custom": { - "xLabel": "Kanchipuram", - "yLabel": "150 100" - }, - "category": "Kanchipuram", - "y": 150100 - }, - { - "custom": { - "xLabel": "Davangere", - "yLabel": "266 082" - }, - "category": "Davangere", - "y": 266082 - }, - { - "custom": { - "xLabel": "Juliaca", - "yLabel": "142 576" - }, - "category": "Juliaca", - "y": 142576 - }, - { - "custom": { - "xLabel": "Anda", - "yLabel": "136 446" - }, - "category": "Anda", - "y": 136446 - }, - { - "custom": { - "xLabel": "Richmond", - "yLabel": "197 790" - }, - "category": "Richmond", - "y": 197790 - }, - { - "custom": { - "xLabel": "Jaranwala", - "yLabel": "103 300" - }, - "category": "Jaranwala", - "y": 103300 - }, - { - "custom": { - "xLabel": "Nukus", - "yLabel": "194 100" - }, - "category": "Nukus", - "y": 194100 - }, - { - "custom": { - "xLabel": "Dodoma", - "yLabel": "189 000" - }, - "category": "Dodoma", - "y": 189000 - }, - { - "custom": { - "xLabel": "Kitakyushu", - "yLabel": "1 016 264" - }, - "category": "Kitakyushu", - "y": 1016264 - }, - { - "custom": { - "xLabel": "Alwar", - "yLabel": "205 086" - }, - "category": "Alwar", - "y": 205086 - }, - { - "custom": { - "xLabel": "Aleppo", - "yLabel": "1 261 983" - }, - "category": "Aleppo", - "y": 1261983 - }, - { - "custom": { - "xLabel": "Liuzhou", - "yLabel": "610 000" - }, - "category": "Liuzhou", - "y": 610000 - }, - { - "custom": { - "xLabel": "Vung Tau", - "yLabel": "145 145" - }, - "category": "Vung Tau", - "y": 145145 - }, - { - "custom": { - "xLabel": "Usak", - "yLabel": "128 162" - }, - "category": "Usak", - "y": 128162 - }, - { - "custom": { - "xLabel": "Cabo Frio", - "yLabel": "119 503" - }, - "category": "Cabo Frio", - "y": 119503 - }, - { - "custom": { - "xLabel": "Jinmen", - "yLabel": "160 794" - }, - "category": "Jinmen", - "y": 160794 - }, - { - "custom": { - "xLabel": "Tlalnepantla de Baz", - "yLabel": "720 755" - }, - "category": "Tlalnepantla de Baz", - "y": 720755 - }, - { - "custom": { - "xLabel": "Male", - "yLabel": "71 000" - }, - "category": "Male", - "y": 71000 - }, - { - "custom": { - "xLabel": "Marilao", - "yLabel": "101 017" - }, - "category": "Marilao", - "y": 101017 - }, - { - "custom": { - "xLabel": "Carapicuíba", - "yLabel": "357 552" - }, - "category": "Carapicuíba", - "y": 357552 - }, - { - "custom": { - "xLabel": "Dortmund", - "yLabel": "590 213" - }, - "category": "Dortmund", - "y": 590213 - }, - { - "custom": { - "xLabel": "Vaduz", - "yLabel": "5 043" - }, - "category": "Vaduz", - "y": 5043 - }, - { - "custom": { - "xLabel": "Seto", - "yLabel": "130 470" - }, - "category": "Seto", - "y": 130470 - }, - { - "custom": { - "xLabel": "Barrackpur", - "yLabel": "133 265" - }, - "category": "Barrackpur", - "y": 133265 - }, - { - "custom": { - "xLabel": "Sagar", - "yLabel": "195 346" - }, - "category": "Sagar", - "y": 195346 - }, - { - "custom": { - "xLabel": "Kuala Terengganu", - "yLabel": "228 119" - }, - "category": "Kuala Terengganu", - "y": 228119 - }, - { - "custom": { - "xLabel": "Rondonópolis", - "yLabel": "155 115" - }, - "category": "Rondonópolis", - "y": 155115 - }, - { - "custom": { - "xLabel": "Bursa", - "yLabel": "1 095 842" - }, - "category": "Bursa", - "y": 1095842 - }, - { - "custom": { - "xLabel": "Songkhla", - "yLabel": "94 900" - }, - "category": "Songkhla", - "y": 94900 - }, - { - "custom": { - "xLabel": "Mymensingh", - "yLabel": "188 713" - }, - "category": "Mymensingh", - "y": 188713 - }, - { - "custom": { - "xLabel": "Talkha", - "yLabel": "97 700" - }, - "category": "Talkha", - "y": 97700 - }, - { - "custom": { - "xLabel": "Taejon", - "yLabel": "1 425 835" - }, - "category": "Taejon", - "y": 1425835 - }, - { - "custom": { - "xLabel": "Corpus Christi", - "yLabel": "277 454" - }, - "category": "Corpus Christi", - "y": 277454 - }, - { - "custom": { - "xLabel": "Mary", - "yLabel": "101 000" - }, - "category": "Mary", - "y": 101000 - }, - { - "custom": { - "xLabel": "Yaren", - "yLabel": "559" - }, - "category": "Yaren", - "y": 559 - }, - { - "custom": { - "xLabel": "Madurai", - "yLabel": "977 856" - }, - "category": "Madurai", - "y": 977856 - }, - { - "custom": { - "xLabel": "Santo Domingo de Guzmán", - "yLabel": "1 609 966" - }, - "category": "Santo Domingo de Guzmán", - "y": 1609966 - }, - { - "custom": { - "xLabel": "Arak", - "yLabel": "380 755" - }, - "category": "Arak", - "y": 380755 - }, - { - "custom": { - "xLabel": "Shenyang", - "yLabel": "4 265 200" - }, - "category": "Shenyang", - "y": 4265200 - }, - { - "custom": { - "xLabel": "Miandoab", - "yLabel": "90 100" - }, - "category": "Miandoab", - "y": 90100 - }, - { - "custom": { - "xLabel": "Suqian", - "yLabel": "105 021" - }, - "category": "Suqian", - "y": 105021 - }, - { - "custom": { - "xLabel": "Teófilo Otoni", - "yLabel": "124 489" - }, - "category": "Teófilo Otoni", - "y": 124489 - }, - { - "custom": { - "xLabel": "Battambang", - "yLabel": "129 800" - }, - "category": "Battambang", - "y": 129800 - }, - { - "custom": { - "xLabel": "Veraval", - "yLabel": "123 000" - }, - "category": "Veraval", - "y": 123000 - }, - { - "custom": { - "xLabel": "Guanare", - "yLabel": "125 621" - }, - "category": "Guanare", - "y": 125621 - }, - { - "custom": { - "xLabel": "Spanish Town", - "yLabel": "110 379" - }, - "category": "Spanish Town", - "y": 110379 - }, - { - "custom": { - "xLabel": "Uitenhage", - "yLabel": "192 120" - }, - "category": "Uitenhage", - "y": 192120 - }, - { - "custom": { - "xLabel": "Lutsk", - "yLabel": "217 000" - }, - "category": "Lutsk", - "y": 217000 - }, - { - "custom": { - "xLabel": "Ananindeua", - "yLabel": "400 940" - }, - "category": "Ananindeua", - "y": 400940 - }, - { - "custom": { - "xLabel": "El Paso", - "yLabel": "563 662" - }, - "category": "El Paso", - "y": 563662 - }, - { - "custom": { - "xLabel": "al-Dammam", - "yLabel": "482 300" - }, - "category": "al-Dammam", - "y": 482300 - }, - { - "custom": { - "xLabel": "Šiauliai", - "yLabel": "146 563" - }, - "category": "Šiauliai", - "y": 146563 - }, - { - "custom": { - "xLabel": "Jieyang", - "yLabel": "98 531" - }, - "category": "Jieyang", - "y": 98531 - }, - { - "custom": { - "xLabel": "Tartu", - "yLabel": "101 246" - }, - "category": "Tartu", - "y": 101246 - }, - { - "custom": { - "xLabel": "Jiujiang", - "yLabel": "291 187" - }, - "category": "Jiujiang", - "y": 291187 - }, - { - "custom": { - "xLabel": "Bagé", - "yLabel": "120 793" - }, - "category": "Bagé", - "y": 120793 - }, - { - "custom": { - "xLabel": "Leninsk-Kuznetski", - "yLabel": "113 800" - }, - "category": "Leninsk-Kuznetski", - "y": 113800 - }, - { - "custom": { - "xLabel": "Makati", - "yLabel": "444 867" - }, - "category": "Makati", - "y": 444867 - }, - { - "custom": { - "xLabel": "Ulan Bator", - "yLabel": "773 700" - }, - "category": "Ulan Bator", - "y": 773700 - }, - { - "custom": { - "xLabel": "Codó", - "yLabel": "103 153" - }, - "category": "Codó", - "y": 103153 - }, - { - "custom": { - "xLabel": "Sousse", - "yLabel": "145 900" - }, - "category": "Sousse", - "y": 145900 - }, - { - "custom": { - "xLabel": "Chofu", - "yLabel": "201 585" - }, - "category": "Chofu", - "y": 201585 - }, - { - "custom": { - "xLabel": "Meycauayan", - "yLabel": "163 037" - }, - "category": "Meycauayan", - "y": 163037 - }, - { - "custom": { - "xLabel": "Maikop", - "yLabel": "167 300" - }, - "category": "Maikop", - "y": 167300 - }, - { - "custom": { - "xLabel": "Girardot", - "yLabel": "110 963" - }, - "category": "Girardot", - "y": 110963 - }, - { - "custom": { - "xLabel": "Lanzhou", - "yLabel": "1 565 800" - }, - "category": "Lanzhou", - "y": 1565800 - }, - { - "custom": { - "xLabel": "Edirne", - "yLabel": "123 383" - }, - "category": "Edirne", - "y": 123383 - }, - { - "custom": { - "xLabel": "Kars", - "yLabel": "93 000" - }, - "category": "Kars", - "y": 93000 - }, - { - "custom": { - "xLabel": "Jaboatão dos Guararapes", - "yLabel": "558 680" - }, - "category": "Jaboatão dos Guararapes", - "y": 558680 - }, - { - "custom": { - "xLabel": "Mekka", - "yLabel": "965 700" - }, - "category": "Mekka", - "y": 965700 - }, - { - "custom": { - "xLabel": "Yixing", - "yLabel": "200 824" - }, - "category": "Yixing", - "y": 200824 - }, - { - "custom": { - "xLabel": "Godoy Cruz", - "yLabel": "206 998" - }, - "category": "Godoy Cruz", - "y": 206998 - }, - { - "custom": { - "xLabel": "Hegang", - "yLabel": "520 000" - }, - "category": "Hegang", - "y": 520000 - }, - { - "custom": { - "xLabel": "Pudukkottai", - "yLabel": "98 619" - }, - "category": "Pudukkottai", - "y": 98619 - }, - { - "custom": { - "xLabel": "Silay", - "yLabel": "107 722" - }, - "category": "Silay", - "y": 107722 - }, - { - "custom": { - "xLabel": "Germiston", - "yLabel": "164 252" - }, - "category": "Germiston", - "y": 164252 - }, - { - "custom": { - "xLabel": "Verona", - "yLabel": "255 268" - }, - "category": "Verona", - "y": 255268 - }, - { - "custom": { - "xLabel": "Abeokuta", - "yLabel": "427 400" - }, - "category": "Abeokuta", - "y": 427400 - }, - { - "custom": { - "xLabel": "Victoria de las Tunas", - "yLabel": "132 350" - }, - "category": "Victoria de las Tunas", - "y": 132350 - }, - { - "custom": { - "xLabel": "Tagum", - "yLabel": "179 531" - }, - "category": "Tagum", - "y": 179531 - }, - { - "custom": { - "xLabel": "Sunggal", - "yLabel": "92 300" - }, - "category": "Sunggal", - "y": 92300 - }, - { - "custom": { - "xLabel": "Eastbourne", - "yLabel": "90 000" - }, - "category": "Eastbourne", - "y": 90000 - }, - { - "custom": { - "xLabel": "Paranaguá", - "yLabel": "126 076" - }, - "category": "Paranaguá", - "y": 126076 - }, - { - "custom": { - "xLabel": "Bengkulu", - "yLabel": "146 439" - }, - "category": "Bengkulu", - "y": 146439 - }, - { - "custom": { - "xLabel": "Shibin al-Kawm", - "yLabel": "159 909" - }, - "category": "Shibin al-Kawm", - "y": 159909 - }, - { - "custom": { - "xLabel": "Kaiyuan", - "yLabel": "124 219" - }, - "category": "Kaiyuan", - "y": 124219 - }, - { - "custom": { - "xLabel": "Manaus", - "yLabel": "1 255 049" - }, - "category": "Manaus", - "y": 1255049 - }, - { - "custom": { - "xLabel": "Kimje", - "yLabel": "115 427" - }, - "category": "Kimje", - "y": 115427 - }, - { - "custom": { - "xLabel": "Taitung", - "yLabel": "111 039" - }, - "category": "Taitung", - "y": 111039 - }, - { - "custom": { - "xLabel": "Brasília", - "yLabel": "1 969 868" - }, - "category": "Brasília", - "y": 1969868 - }, - { - "custom": { - "xLabel": "Akishima", - "yLabel": "106 914" - }, - "category": "Akishima", - "y": 106914 - }, - { - "custom": { - "xLabel": "Changshu", - "yLabel": "181 805" - }, - "category": "Changshu", - "y": 181805 - }, - { - "custom": { - "xLabel": "General Trias", - "yLabel": "107 691" - }, - "category": "General Trias", - "y": 107691 - }, - { - "custom": { - "xLabel": "Podolsk", - "yLabel": "194 300" - }, - "category": "Podolsk", - "y": 194300 - }, - { - "custom": { - "xLabel": "Serang", - "yLabel": "122 400" - }, - "category": "Serang", - "y": 122400 - }, - { - "custom": { - "xLabel": "Simi Valley", - "yLabel": "111 351" - }, - "category": "Simi Valley", - "y": 111351 - }, - { - "custom": { - "xLabel": "Peking", - "yLabel": "7 472 000" - }, - "category": "Peking", - "y": 7472000 - }, - { - "custom": { - "xLabel": "Izevsk", - "yLabel": "652 800" - }, - "category": "Izevsk", - "y": 652800 - }, - { - "custom": { - "xLabel": "Santipur", - "yLabel": "109 956" - }, - "category": "Santipur", - "y": 109956 - }, - { - "custom": { - "xLabel": "Mbandaka", - "yLabel": "169 841" - }, - "category": "Mbandaka", - "y": 169841 - }, - { - "custom": { - "xLabel": "Tabora", - "yLabel": "92 800" - }, - "category": "Tabora", - "y": 92800 - }, - { - "custom": { - "xLabel": "Naihati", - "yLabel": "132 701" - }, - "category": "Naihati", - "y": 132701 - }, - { - "custom": { - "xLabel": "Orange", - "yLabel": "128 821" - }, - "category": "Orange", - "y": 128821 - }, - { - "custom": { - "xLabel": "Messina", - "yLabel": "259 156" - }, - "category": "Messina", - "y": 259156 - }, - { - "custom": { - "xLabel": "Montréal", - "yLabel": "1 016 376" - }, - "category": "Montréal", - "y": 1016376 - }, - { - "custom": { - "xLabel": "Ankara", - "yLabel": "3 038 159" - }, - "category": "Ankara", - "y": 3038159 - }, - { - "custom": { - "xLabel": "Pathankot", - "yLabel": "123 930" - }, - "category": "Pathankot", - "y": 123930 - }, - { - "custom": { - "xLabel": "Linhares", - "yLabel": "106 278" - }, - "category": "Linhares", - "y": 106278 - }, - { - "custom": { - "xLabel": "Fürth", - "yLabel": "109 771" - }, - "category": "Fürth", - "y": 109771 - }, - { - "custom": { - "xLabel": "Sandakan", - "yLabel": "125 841" - }, - "category": "Sandakan", - "y": 125841 - }, - { - "custom": { - "xLabel": "Petropavlovsk-Kamtšatski", - "yLabel": "194 100" - }, - "category": "Petropavlovsk-Kamtšatski", - "y": 194100 - }, - { - "custom": { - "xLabel": "Città del Vaticano", - "yLabel": "455" - }, - "category": "Città del Vaticano", - "y": 455 - }, - { - "custom": { - "xLabel": "Ann Arbor", - "yLabel": "114 024" - }, - "category": "Ann Arbor", - "y": 114024 - }, - { - "custom": { - "xLabel": "Kisangani", - "yLabel": "417 517" - }, - "category": "Kisangani", - "y": 417517 - }, - { - "custom": { - "xLabel": "Chungho", - "yLabel": "392 176" - }, - "category": "Chungho", - "y": 392176 - }, - { - "custom": { - "xLabel": "Shahr-e Kord", - "yLabel": "100 477" - }, - "category": "Shahr-e Kord", - "y": 100477 - }, - { - "custom": { - "xLabel": "Liberec", - "yLabel": "99 155" - }, - "category": "Liberec", - "y": 99155 - }, - { - "custom": { - "xLabel": "Chilapa de Alvarez", - "yLabel": "102 716" - }, - "category": "Chilapa de Alvarez", - "y": 102716 - }, - { - "custom": { - "xLabel": "Flying Fish Cove", - "yLabel": "700" - }, - "category": "Flying Fish Cove", - "y": 700 - }, - { - "custom": { - "xLabel": "Shanghai", - "yLabel": "9 696 300" - }, - "category": "Shanghai", - "y": 9696300 - }, - { - "custom": { - "xLabel": "Novo Hamburgo", - "yLabel": "239 940" - }, - "category": "Novo Hamburgo", - "y": 239940 - }, - { - "custom": { - "xLabel": "Daly City", - "yLabel": "103 621" - }, - "category": "Daly City", - "y": 103621 - }, - { - "custom": { - "xLabel": "Fu´an", - "yLabel": "105 265" - }, - "category": "Fu´an", - "y": 105265 - }, - { - "custom": { - "xLabel": "Arequipa", - "yLabel": "762 000" - }, - "category": "Arequipa", - "y": 762000 - }, - { - "custom": { - "xLabel": "Bamako", - "yLabel": "809 552" - }, - "category": "Bamako", - "y": 809552 - }, - { - "custom": { - "xLabel": "San Pedro de la Paz", - "yLabel": "91 684" - }, - "category": "San Pedro de la Paz", - "y": 91684 - }, - { - "custom": { - "xLabel": "Boulder", - "yLabel": "91 238" - }, - "category": "Boulder", - "y": 91238 - }, - { - "custom": { - "xLabel": "Zanzibar", - "yLabel": "157 634" - }, - "category": "Zanzibar", - "y": 157634 - }, - { - "custom": { - "xLabel": "Seversk", - "yLabel": "118 600" - }, - "category": "Seversk", - "y": 118600 - }, - { - "custom": { - "xLabel": "Yanbu", - "yLabel": "119 800" - }, - "category": "Yanbu", - "y": 119800 - }, - { - "custom": { - "xLabel": "Himki", - "yLabel": "133 700" - }, - "category": "Himki", - "y": 133700 - }, - { - "custom": { - "xLabel": "Zinacantepec", - "yLabel": "121 715" - }, - "category": "Zinacantepec", - "y": 121715 - }, - { - "custom": { - "xLabel": "Yao", - "yLabel": "276 421" - }, - "category": "Yao", - "y": 276421 - }, - { - "custom": { - "xLabel": "Kazan", - "yLabel": "1 101 000" - }, - "category": "Kazan", - "y": 1101000 - }, - { - "custom": { - "xLabel": "Mocuba", - "yLabel": "124 700" - }, - "category": "Mocuba", - "y": 124700 - }, - { - "custom": { - "xLabel": "Memphis", - "yLabel": "650 100" - }, - "category": "Memphis", - "y": 650100 - }, - { - "custom": { - "xLabel": "Coronel", - "yLabel": "93 061" - }, - "category": "Coronel", - "y": 93061 - }, - { - "custom": { - "xLabel": "Los Angeles", - "yLabel": "3 694 820" - }, - "category": "Los Angeles", - "y": 3694820 - }, - { - "custom": { - "xLabel": "Río Bravo", - "yLabel": "103 901" - }, - "category": "Río Bravo", - "y": 103901 - }, - { - "custom": { - "xLabel": "Kashiwazaki", - "yLabel": "91 229" - }, - "category": "Kashiwazaki", - "y": 91229 - }, - { - "custom": { - "xLabel": "Jerusalem", - "yLabel": "633 700" - }, - "category": "Jerusalem", - "y": 633700 - }, - { - "custom": { - "xLabel": "Gweru", - "yLabel": "128 037" - }, - "category": "Gweru", - "y": 128037 - }, - { - "custom": { - "xLabel": "Taizhou", - "yLabel": "152 442" - }, - "category": "Taizhou", - "y": 152442 - }, - { - "custom": { - "xLabel": "Mishima", - "yLabel": "109 699" - }, - "category": "Mishima", - "y": 109699 - }, - { - "custom": { - "xLabel": "Valletta", - "yLabel": "7 073" - }, - "category": "Valletta", - "y": 7073 - }, - { - "custom": { - "xLabel": "Derby", - "yLabel": "236 000" - }, - "category": "Derby", - "y": 236000 - }, - { - "custom": { - "xLabel": "Mobara", - "yLabel": "91 664" - }, - "category": "Mobara", - "y": 91664 - }, - { - "custom": { - "xLabel": "Guayaquil", - "yLabel": "2 070 040" - }, - "category": "Guayaquil", - "y": 2070040 - }, - { - "custom": { - "xLabel": "Lengshuijiang", - "yLabel": "137 994" - }, - "category": "Lengshuijiang", - "y": 137994 - }, - { - "custom": { - "xLabel": "Benxi", - "yLabel": "770 000" - }, - "category": "Benxi", - "y": 770000 - }, - { - "custom": { - "xLabel": "Baidyabati", - "yLabel": "90 601" - }, - "category": "Baidyabati", - "y": 90601 - }, - { - "custom": { - "xLabel": "Safi", - "yLabel": "262 300" - }, - "category": "Safi", - "y": 262300 - }, - { - "custom": { - "xLabel": "Qina", - "yLabel": "171 275" - }, - "category": "Qina", - "y": 171275 - }, - { - "custom": { - "xLabel": "Ghardaïa", - "yLabel": "89 415" - }, - "category": "Ghardaïa", - "y": 89415 - }, - { - "custom": { - "xLabel": "Dordrecht", - "yLabel": "119 811" - }, - "category": "Dordrecht", - "y": 119811 - }, - { - "custom": { - "xLabel": "Sri Jayawardenepura Kotte", - "yLabel": "118 000" - }, - "category": "Sri Jayawardenepura Kotte", - "y": 118000 - }, - { - "custom": { - "xLabel": "Rennes", - "yLabel": "206 229" - }, - "category": "Rennes", - "y": 206229 - }, - { - "custom": { - "xLabel": "El Cajon", - "yLabel": "94 578" - }, - "category": "El Cajon", - "y": 94578 - }, - { - "custom": { - "xLabel": "Pavlograd", - "yLabel": "127 000" - }, - "category": "Pavlograd", - "y": 127000 - }, - { - "custom": { - "xLabel": "Rosario", - "yLabel": "907 718" - }, - "category": "Rosario", - "y": 907718 - }, - { - "custom": { - "xLabel": "Kota", - "yLabel": "537 371" - }, - "category": "Kota", - "y": 537371 - }, - { - "custom": { - "xLabel": "Kidapawan", - "yLabel": "101 205" - }, - "category": "Kidapawan", - "y": 101205 - }, - { - "custom": { - "xLabel": "Paterson", - "yLabel": "149 222" - }, - "category": "Paterson", - "y": 149222 - }, - { - "custom": { - "xLabel": "Kutaisi", - "yLabel": "240 900" - }, - "category": "Kutaisi", - "y": 240900 - }, - { - "custom": { - "xLabel": "Yuncheng", - "yLabel": "108 359" - }, - "category": "Yuncheng", - "y": 108359 - }, - { - "custom": { - "xLabel": "Daugavpils", - "yLabel": "114 829" - }, - "category": "Daugavpils", - "y": 114829 - }, - { - "custom": { - "xLabel": "Piedras Negras", - "yLabel": "127 898" - }, - "category": "Piedras Negras", - "y": 127898 - }, - { - "custom": { - "xLabel": "Sertãozinho", - "yLabel": "98 140" - }, - "category": "Sertãozinho", - "y": 98140 - }, - { - "custom": { - "xLabel": "Machala", - "yLabel": "210 368" - }, - "category": "Machala", - "y": 210368 - }, - { - "custom": { - "xLabel": "Higashiosaka", - "yLabel": "517 785" - }, - "category": "Higashiosaka", - "y": 517785 - }, - { - "custom": { - "xLabel": "Rochdale", - "yLabel": "94 313" - }, - "category": "Rochdale", - "y": 94313 - }, - { - "custom": { - "xLabel": "Vaughan", - "yLabel": "147 889" - }, - "category": "Vaughan", - "y": 147889 - }, - { - "custom": { - "xLabel": "Radom", - "yLabel": "232 262" - }, - "category": "Radom", - "y": 232262 - }, - { - "custom": { - "xLabel": "Etobicoke", - "yLabel": "348 845" - }, - "category": "Etobicoke", - "y": 348845 - }, - { - "custom": { - "xLabel": "Kollam (Quilon)", - "yLabel": "139 852" - }, - "category": "Kollam (Quilon)", - "y": 139852 - }, - { - "custom": { - "xLabel": "Novošahtinsk", - "yLabel": "101 900" - }, - "category": "Novošahtinsk", - "y": 101900 - }, - { - "custom": { - "xLabel": "Rostov-na-Donu", - "yLabel": "1 012 700" - }, - "category": "Rostov-na-Donu", - "y": 1012700 - }, - { - "custom": { - "xLabel": "Jiaxing", - "yLabel": "211 526" - }, - "category": "Jiaxing", - "y": 211526 - }, - { - "custom": { - "xLabel": "Taytay", - "yLabel": "198 183" - }, - "category": "Taytay", - "y": 198183 - }, - { - "custom": { - "xLabel": "Hagen", - "yLabel": "205 201" - }, - "category": "Hagen", - "y": 205201 - }, - { - "custom": { - "xLabel": "Calapan", - "yLabel": "105 910" - }, - "category": "Calapan", - "y": 105910 - }, - { - "custom": { - "xLabel": "Dabrowa Górnicza", - "yLabel": "131 037" - }, - "category": "Dabrowa Górnicza", - "y": 131037 - }, - { - "custom": { - "xLabel": "Kasur", - "yLabel": "241 649" - }, - "category": "Kasur", - "y": 241649 - }, - { - "custom": { - "xLabel": "Nha Trang", - "yLabel": "221 331" - }, - "category": "Nha Trang", - "y": 221331 - }, - { - "custom": { - "xLabel": "Kataka (Cuttack)", - "yLabel": "403 418" - }, - "category": "Kataka (Cuttack)", - "y": 403418 - }, - { - "custom": { - "xLabel": "Hikone", - "yLabel": "105 508" - }, - "category": "Hikone", - "y": 105508 - }, - { - "custom": { - "xLabel": "Kanpur", - "yLabel": "1 874 409" - }, - "category": "Kanpur", - "y": 1874409 - }, - { - "custom": { - "xLabel": "Putian", - "yLabel": "91 030" - }, - "category": "Putian", - "y": 91030 - }, - { - "custom": { - "xLabel": "Chingola", - "yLabel": "142 400" - }, - "category": "Chingola", - "y": 142400 - }, - { - "custom": { - "xLabel": "Kabwe", - "yLabel": "154 300" - }, - "category": "Kabwe", - "y": 154300 - }, - { - "custom": { - "xLabel": "Misato", - "yLabel": "132 957" - }, - "category": "Misato", - "y": 132957 - }, - { - "custom": { - "xLabel": "Yamatokoriyama", - "yLabel": "95 165" - }, - "category": "Yamatokoriyama", - "y": 95165 - }, - { - "custom": { - "xLabel": "Hitachi", - "yLabel": "196 622" - }, - "category": "Hitachi", - "y": 196622 - }, - { - "custom": { - "xLabel": "Isparta", - "yLabel": "121 911" - }, - "category": "Isparta", - "y": 121911 - }, - { - "custom": { - "xLabel": "Tantoyuca", - "yLabel": "94 709" - }, - "category": "Tantoyuca", - "y": 94709 - }, - { - "custom": { - "xLabel": "Kigali", - "yLabel": "286 000" - }, - "category": "Kigali", - "y": 286000 - }, - { - "custom": { - "xLabel": "Springfield", - "yLabel": "152 082" - }, - "category": "Springfield", - "y": 152082 - }, - { - "custom": { - "xLabel": "Surgut", - "yLabel": "274 900" - }, - "category": "Surgut", - "y": 274900 - }, - { - "custom": { - "xLabel": "Zeleznogorsk", - "yLabel": "96 900" - }, - "category": "Zeleznogorsk", - "y": 96900 - }, - { - "custom": { - "xLabel": "Tiraspol", - "yLabel": "194 300" - }, - "category": "Tiraspol", - "y": 194300 - }, - { - "custom": { - "xLabel": "Itami", - "yLabel": "190 886" - }, - "category": "Itami", - "y": 190886 - }, - { - "custom": { - "xLabel": "Chiang Mai", - "yLabel": "171 100" - }, - "category": "Chiang Mai", - "y": 171100 - }, - { - "custom": { - "xLabel": "Kobe", - "yLabel": "1 425 139" - }, - "category": "Kobe", - "y": 1425139 - }, - { - "custom": { - "xLabel": "Moji das Cruzes", - "yLabel": "339 194" - }, - "category": "Moji das Cruzes", - "y": 339194 - }, - { - "custom": { - "xLabel": "Raj Nandgaon", - "yLabel": "125 371" - }, - "category": "Raj Nandgaon", - "y": 125371 - }, - { - "custom": { - "xLabel": "Salerno", - "yLabel": "142 055" - }, - "category": "Salerno", - "y": 142055 - }, - { - "custom": { - "xLabel": "Sari", - "yLabel": "195 882" - }, - "category": "Sari", - "y": 195882 - }, - { - "custom": { - "xLabel": "Bulaq al-Dakrur", - "yLabel": "148 787" - }, - "category": "Bulaq al-Dakrur", - "y": 148787 - }, - { - "custom": { - "xLabel": "Milano", - "yLabel": "1 300 977" - }, - "category": "Milano", - "y": 1300977 - }, - { - "custom": { - "xLabel": "Ribeirão Preto", - "yLabel": "473 276" - }, - "category": "Ribeirão Preto", - "y": 473276 - }, - { - "custom": { - "xLabel": "Severodvinsk", - "yLabel": "229 300" - }, - "category": "Severodvinsk", - "y": 229300 - }, - { - "custom": { - "xLabel": "Stuttgart", - "yLabel": "582 443" - }, - "category": "Stuttgart", - "y": 582443 - }, - { - "custom": { - "xLabel": "Shaoyang", - "yLabel": "247 227" - }, - "category": "Shaoyang", - "y": 247227 - }, - { - "custom": { - "xLabel": "Ho Chi Minh City", - "yLabel": "3 980 000" - }, - "category": "Ho Chi Minh City", - "y": 3980000 - }, - { - "custom": { - "xLabel": "Györ", - "yLabel": "127 119" - }, - "category": "Györ", - "y": 127119 - }, - { - "custom": { - "xLabel": "East London", - "yLabel": "221 047" - }, - "category": "East London", - "y": 221047 - }, - { - "custom": { - "xLabel": "Vilnius", - "yLabel": "577 969" - }, - "category": "Vilnius", - "y": 577969 - }, - { - "custom": { - "xLabel": "Manzanillo", - "yLabel": "109 350" - }, - "category": "Manzanillo", - "y": 109350 - }, - { - "custom": { - "xLabel": "Suihua", - "yLabel": "227 881" - }, - "category": "Suihua", - "y": 227881 - }, - { - "custom": { - "xLabel": "Americana", - "yLabel": "177 409" - }, - "category": "Americana", - "y": 177409 - }, - { - "custom": { - "xLabel": "Priština", - "yLabel": "155 496" - }, - "category": "Priština", - "y": 155496 - }, - { - "custom": { - "xLabel": "Moji-Guaçu", - "yLabel": "123 782" - }, - "category": "Moji-Guaçu", - "y": 123782 - }, - { - "custom": { - "xLabel": "Barisal", - "yLabel": "170 232" - }, - "category": "Barisal", - "y": 170232 - }, - { - "custom": { - "xLabel": "Moers", - "yLabel": "106 837" - }, - "category": "Moers", - "y": 106837 - }, - { - "custom": { - "xLabel": "Kuala Lumpur", - "yLabel": "1 297 526" - }, - "category": "Kuala Lumpur", - "y": 1297526 - }, - { - "custom": { - "xLabel": "Alexandria", - "yLabel": "128 283" - }, - "category": "Alexandria", - "y": 128283 - }, - { - "custom": { - "xLabel": "Nojabrsk", - "yLabel": "97 300" - }, - "category": "Nojabrsk", - "y": 97300 - }, - { - "custom": { - "xLabel": "Boma", - "yLabel": "135 284" - }, - "category": "Boma", - "y": 135284 - }, - { - "custom": { - "xLabel": "Yuzhou", - "yLabel": "92 889" - }, - "category": "Yuzhou", - "y": 92889 - }, - { - "custom": { - "xLabel": "Hanzhong", - "yLabel": "169 930" - }, - "category": "Hanzhong", - "y": 169930 - }, - { - "custom": { - "xLabel": "Cork", - "yLabel": "127 187" - }, - "category": "Cork", - "y": 127187 - }, - { - "custom": { - "xLabel": "Ladysmith", - "yLabel": "89 292" - }, - "category": "Ladysmith", - "y": 89292 - }, - { - "custom": { - "xLabel": "Embu", - "yLabel": "222 223" - }, - "category": "Embu", - "y": 222223 - }, - { - "custom": { - "xLabel": "Mun-gyong", - "yLabel": "92 239" - }, - "category": "Mun-gyong", - "y": 92239 - }, - { - "custom": { - "xLabel": "Quilpué", - "yLabel": "118 857" - }, - "category": "Quilpué", - "y": 118857 - }, - { - "custom": { - "xLabel": "Pingdu", - "yLabel": "150 123" - }, - "category": "Pingdu", - "y": 150123 - }, - { - "custom": { - "xLabel": "Satu Mare", - "yLabel": "130 059" - }, - "category": "Satu Mare", - "y": 130059 - }, - { - "custom": { - "xLabel": "Modinagar", - "yLabel": "101 660" - }, - "category": "Modinagar", - "y": 101660 - }, - { - "custom": { - "xLabel": "Villavicencio", - "yLabel": "273 140" - }, - "category": "Villavicencio", - "y": 273140 - }, - { - "custom": { - "xLabel": "Kismaayo", - "yLabel": "90 000" - }, - "category": "Kismaayo", - "y": 90000 - }, - { - "custom": { - "xLabel": "Maroua", - "yLabel": "143 000" - }, - "category": "Maroua", - "y": 143000 - }, - { - "custom": { - "xLabel": "Plano", - "yLabel": "222 030" - }, - "category": "Plano", - "y": 222030 - }, - { - "custom": { - "xLabel": "Rawalpindi", - "yLabel": "1 406 214" - }, - "category": "Rawalpindi", - "y": 1406214 - }, - { - "custom": { - "xLabel": "Daska", - "yLabel": "101 500" - }, - "category": "Daska", - "y": 101500 - }, - { - "custom": { - "xLabel": "Porto-Novo", - "yLabel": "194 000" - }, - "category": "Porto-Novo", - "y": 194000 - }, - { - "custom": { - "xLabel": "Tama", - "yLabel": "146 712" - }, - "category": "Tama", - "y": 146712 - }, - { - "custom": { - "xLabel": "Citeureup", - "yLabel": "105 100" - }, - "category": "Citeureup", - "y": 105100 - }, - { - "custom": { - "xLabel": "Wadi al-Sir", - "yLabel": "89 104" - }, - "category": "Wadi al-Sir", - "y": 89104 - }, - { - "custom": { - "xLabel": "Melitopol", - "yLabel": "169 000" - }, - "category": "Melitopol", - "y": 169000 - }, - { - "custom": { - "xLabel": "Yibin", - "yLabel": "241 019" - }, - "category": "Yibin", - "y": 241019 - }, - { - "custom": { - "xLabel": "Baotou", - "yLabel": "980 000" - }, - "category": "Baotou", - "y": 980000 - }, - { - "custom": { - "xLabel": "Dibrugarh", - "yLabel": "120 127" - }, - "category": "Dibrugarh", - "y": 120127 - }, - { - "custom": { - "xLabel": "Glasgow", - "yLabel": "619 680" - }, - "category": "Glasgow", - "y": 619680 - }, - { - "custom": { - "xLabel": "Kalisz", - "yLabel": "106 641" - }, - "category": "Kalisz", - "y": 106641 - }, - { - "custom": { - "xLabel": "Likasi", - "yLabel": "299 118" - }, - "category": "Likasi", - "y": 299118 - }, - { - "custom": { - "xLabel": "Tando Adam", - "yLabel": "103 400" - }, - "category": "Tando Adam", - "y": 103400 - }, - { - "custom": { - "xLabel": "Dera Ghazi Khan", - "yLabel": "188 100" - }, - "category": "Dera Ghazi Khan", - "y": 188100 - }, - { - "custom": { - "xLabel": "Goiânia", - "yLabel": "1 056 330" - }, - "category": "Goiânia", - "y": 1056330 - }, - { - "custom": { - "xLabel": "Berhampore (Baharampur)", - "yLabel": "115 144" - }, - "category": "Berhampore (Baharampur)", - "y": 115144 - }, - { - "custom": { - "xLabel": "Volgodonsk", - "yLabel": "178 200" - }, - "category": "Volgodonsk", - "y": 178200 - }, - { - "custom": { - "xLabel": "Legnica", - "yLabel": "109 335" - }, - "category": "Legnica", - "y": 109335 - }, - { - "custom": { - "xLabel": "Bordeaux", - "yLabel": "215 363" - }, - "category": "Bordeaux", - "y": 215363 - }, - { - "custom": { - "xLabel": "San Isidro", - "yLabel": "306 341" - }, - "category": "San Isidro", - "y": 306341 - }, - { - "custom": { - "xLabel": "Kawagoe", - "yLabel": "327 211" - }, - "category": "Kawagoe", - "y": 327211 - }, - { - "custom": { - "xLabel": "Yong-in", - "yLabel": "242 643" - }, - "category": "Yong-in", - "y": 242643 - }, - { - "custom": { - "xLabel": "Hanam", - "yLabel": "115 812" - }, - "category": "Hanam", - "y": 115812 - }, - { - "custom": { - "xLabel": "Asaka", - "yLabel": "114 815" - }, - "category": "Asaka", - "y": 114815 - }, - { - "custom": { - "xLabel": "Comalcalco", - "yLabel": "164 640" - }, - "category": "Comalcalco", - "y": 164640 - }, - { - "custom": { - "xLabel": "Ziguinchor", - "yLabel": "192 000" - }, - "category": "Ziguinchor", - "y": 192000 - }, - { - "custom": { - "xLabel": "Serov", - "yLabel": "100 400" - }, - "category": "Serov", - "y": 100400 - }, - { - "custom": { - "xLabel": "Lakewood", - "yLabel": "144 126" - }, - "category": "Lakewood", - "y": 144126 - }, - { - "custom": { - "xLabel": "Iwo", - "yLabel": "362 000" - }, - "category": "Iwo", - "y": 362000 - }, - { - "custom": { - "xLabel": "Reynosa", - "yLabel": "419 776" - }, - "category": "Reynosa", - "y": 419776 - }, - { - "custom": { - "xLabel": "Denizli", - "yLabel": "253 848" - }, - "category": "Denizli", - "y": 253848 - }, - { - "custom": { - "xLabel": "Hyderabad", - "yLabel": "1 151 274" - }, - "category": "Hyderabad", - "y": 1151274 - }, - { - "custom": { - "xLabel": "Jamshedpur", - "yLabel": "460 577" - }, - "category": "Jamshedpur", - "y": 460577 - }, - { - "custom": { - "xLabel": "Bandar Lampung", - "yLabel": "680 332" - }, - "category": "Bandar Lampung", - "y": 680332 - }, - { - "custom": { - "xLabel": "Villa Nueva", - "yLabel": "101 295" - }, - "category": "Villa Nueva", - "y": 101295 - }, - { - "custom": { - "xLabel": "Ardebil", - "yLabel": "340 386" - }, - "category": "Ardebil", - "y": 340386 - }, - { - "custom": { - "xLabel": "Rizhao", - "yLabel": "185 048" - }, - "category": "Rizhao", - "y": 185048 - }, - { - "custom": { - "xLabel": "Abohar", - "yLabel": "107 163" - }, - "category": "Abohar", - "y": 107163 - }, - { - "custom": { - "xLabel": "Escondido", - "yLabel": "133 559" - }, - "category": "Escondido", - "y": 133559 - }, - { - "custom": { - "xLabel": "Newport", - "yLabel": "139 000" - }, - "category": "Newport", - "y": 139000 - }, - { - "custom": { - "xLabel": "Lanús", - "yLabel": "469 735" - }, - "category": "Lanús", - "y": 469735 - }, - { - "custom": { - "xLabel": "Tours", - "yLabel": "132 820" - }, - "category": "Tours", - "y": 132820 - }, - { - "custom": { - "xLabel": "Wloclawek", - "yLabel": "123 373" - }, - "category": "Wloclawek", - "y": 123373 - }, - { - "custom": { - "xLabel": "Nam Dinh", - "yLabel": "171 699" - }, - "category": "Nam Dinh", - "y": 171699 - }, - { - "custom": { - "xLabel": "Shuangcheng", - "yLabel": "142 659" - }, - "category": "Shuangcheng", - "y": 142659 - }, - { - "custom": { - "xLabel": "Pontianak", - "yLabel": "409 632" - }, - "category": "Pontianak", - "y": 409632 - }, - { - "custom": { - "xLabel": "Luchou", - "yLabel": "160 516" - }, - "category": "Luchou", - "y": 160516 - }, - { - "custom": { - "xLabel": "Cottbus", - "yLabel": "110 894" - }, - "category": "Cottbus", - "y": 110894 - }, - { - "custom": { - "xLabel": "Hadano", - "yLabel": "166 512" - }, - "category": "Hadano", - "y": 166512 - }, - { - "custom": { - "xLabel": "Cotia", - "yLabel": "140 042" - }, - "category": "Cotia", - "y": 140042 - }, - { - "custom": { - "xLabel": "Kyiv", - "yLabel": "2 624 000" - }, - "category": "Kyiv", - "y": 2624000 - }, - { - "custom": { - "xLabel": "Wuhan", - "yLabel": "4 344 600" - }, - "category": "Wuhan", - "y": 4344600 - }, - { - "custom": { - "xLabel": "Reutlingen", - "yLabel": "110 343" - }, - "category": "Reutlingen", - "y": 110343 - }, - { - "custom": { - "xLabel": "Jammu", - "yLabel": "214 737" - }, - "category": "Jammu", - "y": 214737 - }, - { - "custom": { - "xLabel": "Kawasaki", - "yLabel": "1 217 359" - }, - "category": "Kawasaki", - "y": 1217359 - }, - { - "custom": { - "xLabel": "Nawabganj", - "yLabel": "130 577" - }, - "category": "Nawabganj", - "y": 130577 - }, - { - "custom": { - "xLabel": "Kupang", - "yLabel": "129 300" - }, - "category": "Kupang", - "y": 129300 - }, - { - "custom": { - "xLabel": "West Covina", - "yLabel": "105 080" - }, - "category": "West Covina", - "y": 105080 - }, - { - "custom": { - "xLabel": "Yosu", - "yLabel": "183 596" - }, - "category": "Yosu", - "y": 183596 - }, - { - "custom": { - "xLabel": "Takaoka", - "yLabel": "174 380" - }, - "category": "Takaoka", - "y": 174380 - }, - { - "custom": { - "xLabel": "Cochin (Kochi)", - "yLabel": "564 589" - }, - "category": "Cochin (Kochi)", - "y": 564589 - }, - { - "custom": { - "xLabel": "Portoviejo", - "yLabel": "176 413" - }, - "category": "Portoviejo", - "y": 176413 - }, - { - "custom": { - "xLabel": "Mirpur Khas", - "yLabel": "184 500" - }, - "category": "Mirpur Khas", - "y": 184500 - }, - { - "custom": { - "xLabel": "Pinang", - "yLabel": "219 603" - }, - "category": "Pinang", - "y": 219603 - }, - { - "custom": { - "xLabel": "Hamilton", - "yLabel": "335 614" - }, - "category": "Hamilton", - "y": 335614 - }, - { - "custom": { - "xLabel": "Wakayama", - "yLabel": "391 233" - }, - "category": "Wakayama", - "y": 391233 - }, - { - "custom": { - "xLabel": "Kowloon and New Kowloon", - "yLabel": "1 987 996" - }, - "category": "Kowloon and New Kowloon", - "y": 1987996 - }, - { - "custom": { - "xLabel": "Ipatinga", - "yLabel": "206 338" - }, - "category": "Ipatinga", - "y": 206338 - }, - { - "custom": { - "xLabel": "Sabadell", - "yLabel": "184 859" - }, - "category": "Sabadell", - "y": 184859 - }, - { - "custom": { - "xLabel": "Djougou", - "yLabel": "134 099" - }, - "category": "Djougou", - "y": 134099 - }, - { - "custom": { - "xLabel": "Valenzuela", - "yLabel": "485 433" - }, - "category": "Valenzuela", - "y": 485433 - }, - { - "custom": { - "xLabel": "Bei´an", - "yLabel": "204 899" - }, - "category": "Bei´an", - "y": 204899 - }, - { - "custom": { - "xLabel": "Kanuma", - "yLabel": "93 053" - }, - "category": "Kanuma", - "y": 93053 - }, - { - "custom": { - "xLabel": "Kakinada", - "yLabel": "279 980" - }, - "category": "Kakinada", - "y": 279980 - }, - { - "custom": { - "xLabel": "Dire Dawa", - "yLabel": "164 851" - }, - "category": "Dire Dawa", - "y": 164851 - }, - { - "custom": { - "xLabel": "Hafizabad", - "yLabel": "130 200" - }, - "category": "Hafizabad", - "y": 130200 - }, - { - "custom": { - "xLabel": "Colombo", - "yLabel": "645 000" - }, - "category": "Colombo", - "y": 645000 - }, - { - "custom": { - "xLabel": "Valle de Chalco Solidaridad", - "yLabel": "323 113" - }, - "category": "Valle de Chalco Solidaridad", - "y": 323113 - }, - { - "custom": { - "xLabel": "Kioto", - "yLabel": "1 461 974" - }, - "category": "Kioto", - "y": 1461974 - }, - { - "custom": { - "xLabel": "Urasoe", - "yLabel": "96 002" - }, - "category": "Urasoe", - "y": 96002 - }, - { - "custom": { - "xLabel": "Ivanovo", - "yLabel": "459 200" - }, - "category": "Ivanovo", - "y": 459200 - }, - { - "custom": { - "xLabel": "Nice", - "yLabel": "342 738" - }, - "category": "Nice", - "y": 342738 - }, - { - "custom": { - "xLabel": "Kabankalan", - "yLabel": "149 769" - }, - "category": "Kabankalan", - "y": 149769 - }, - { - "custom": { - "xLabel": "Imus", - "yLabel": "195 482" - }, - "category": "Imus", - "y": 195482 - }, - { - "custom": { - "xLabel": "Nova Iguaçu", - "yLabel": "862 225" - }, - "category": "Nova Iguaçu", - "y": 862225 - }, - { - "custom": { - "xLabel": "Mesa", - "yLabel": "396 375" - }, - "category": "Mesa", - "y": 396375 - }, - { - "custom": { - "xLabel": "Toulouse", - "yLabel": "390 350" - }, - "category": "Toulouse", - "y": 390350 - }, - { - "custom": { - "xLabel": "Prome (Pyay)", - "yLabel": "105 700" - }, - "category": "Prome (Pyay)", - "y": 105700 - }, - { - "custom": { - "xLabel": "Orjol", - "yLabel": "344 500" - }, - "category": "Orjol", - "y": 344500 - }, - { - "custom": { - "xLabel": "Eugene", - "yLabel": "137 893" - }, - "category": "Eugene", - "y": 137893 - }, - { - "custom": { - "xLabel": "Balurghat", - "yLabel": "119 796" - }, - "category": "Balurghat", - "y": 119796 - }, - { - "custom": { - "xLabel": "Las Piñas", - "yLabel": "472 780" - }, - "category": "Las Piñas", - "y": 472780 - }, - { - "custom": { - "xLabel": "Deba Habe", - "yLabel": "138 600" - }, - "category": "Deba Habe", - "y": 138600 - }, - { - "custom": { - "xLabel": "Citrus Heights", - "yLabel": "103 455" - }, - "category": "Citrus Heights", - "y": 103455 - }, - { - "custom": { - "xLabel": "Kalookan", - "yLabel": "1 177 604" - }, - "category": "Kalookan", - "y": 1177604 - }, - { - "custom": { - "xLabel": "Fukaya", - "yLabel": "102 156" - }, - "category": "Fukaya", - "y": 102156 - }, - { - "custom": { - "xLabel": "Loudi", - "yLabel": "128 418" - }, - "category": "Loudi", - "y": 128418 - }, - { - "custom": { - "xLabel": "Avadi", - "yLabel": "183 215" - }, - "category": "Avadi", - "y": 183215 - }, - { - "custom": { - "xLabel": "Qiqihar", - "yLabel": "1 070 000" - }, - "category": "Qiqihar", - "y": 1070000 - }, - { - "custom": { - "xLabel": "Chihuahua", - "yLabel": "670 208" - }, - "category": "Chihuahua", - "y": 670208 - }, - { - "custom": { - "xLabel": "Tondabayashi", - "yLabel": "125 094" - }, - "category": "Tondabayashi", - "y": 125094 - }, - { - "custom": { - "xLabel": "Acheng", - "yLabel": "197 595" - }, - "category": "Acheng", - "y": 197595 - }, - { - "custom": { - "xLabel": "al-Mansura", - "yLabel": "369 621" - }, - "category": "al-Mansura", - "y": 369621 - }, - { - "custom": { - "xLabel": "Blackpool", - "yLabel": "151 000" - }, - "category": "Blackpool", - "y": 151000 - }, - { - "custom": { - "xLabel": "McAllen", - "yLabel": "106 414" - }, - "category": "McAllen", - "y": 106414 - }, - { - "custom": { - "xLabel": "Örebro", - "yLabel": "124 207" - }, - "category": "Örebro", - "y": 124207 - }, - { - "custom": { - "xLabel": "Osaka", - "yLabel": "2 595 674" - }, - "category": "Osaka", - "y": 2595674 - }, - { - "custom": { - "xLabel": "Forlì", - "yLabel": "107 475" - }, - "category": "Forlì", - "y": 107475 - }, - { - "custom": { - "xLabel": "Tapachula", - "yLabel": "271 141" - }, - "category": "Tapachula", - "y": 271141 - }, - { - "custom": { - "xLabel": "Gonbad-e Qabus", - "yLabel": "111 253" - }, - "category": "Gonbad-e Qabus", - "y": 111253 - }, - { - "custom": { - "xLabel": "Regensburg", - "yLabel": "125 236" - }, - "category": "Regensburg", - "y": 125236 - }, - { - "custom": { - "xLabel": "Tepatitlán de Morelos", - "yLabel": "118 948" - }, - "category": "Tepatitlán de Morelos", - "y": 118948 - }, - { - "custom": { - "xLabel": "al-Kut", - "yLabel": "183 183" - }, - "category": "al-Kut", - "y": 183183 - }, - { - "custom": { - "xLabel": "San Salvador de Jujuy", - "yLabel": "178 748" - }, - "category": "San Salvador de Jujuy", - "y": 178748 - }, - { - "custom": { - "xLabel": "Muridke", - "yLabel": "108 600" - }, - "category": "Muridke", - "y": 108600 - }, - { - "custom": { - "xLabel": "Nijmegen", - "yLabel": "152 463" - }, - "category": "Nijmegen", - "y": 152463 - }, - { - "custom": { - "xLabel": "Lyon", - "yLabel": "445 452" - }, - "category": "Lyon", - "y": 445452 - }, - { - "custom": { - "xLabel": "San Juan Bautista Tuxtepec", - "yLabel": "133 675" - }, - "category": "San Juan Bautista Tuxtepec", - "y": 133675 - }, - { - "custom": { - "xLabel": "Xinghua", - "yLabel": "161 910" - }, - "category": "Xinghua", - "y": 161910 - }, - { - "custom": { - "xLabel": "Concepcion", - "yLabel": "115 171" - }, - "category": "Concepcion", - "y": 115171 - }, - { - "custom": { - "xLabel": "Victoria", - "yLabel": "41 000" - }, - "category": "Victoria", - "y": 41000 - }, - { - "custom": { - "xLabel": "Kangnung", - "yLabel": "220 403" - }, - "category": "Kangnung", - "y": 220403 - }, - { - "custom": { - "xLabel": "Berkeley", - "yLabel": "102 743" - }, - "category": "Berkeley", - "y": 102743 - }, - { - "custom": { - "xLabel": "Kashihara", - "yLabel": "124 013" - }, - "category": "Kashihara", - "y": 124013 - }, - { - "custom": { - "xLabel": "Okinawa", - "yLabel": "117 748" - }, - "category": "Okinawa", - "y": 117748 - }, - { - "custom": { - "xLabel": "Krefeld", - "yLabel": "241 769" - }, - "category": "Krefeld", - "y": 241769 - }, - { - "custom": { - "xLabel": "San Buenaventura", - "yLabel": "100 916" - }, - "category": "San Buenaventura", - "y": 100916 - }, - { - "custom": { - "xLabel": "Machida", - "yLabel": "364 197" - }, - "category": "Machida", - "y": 364197 - }, - { - "custom": { - "xLabel": "Santa Ana", - "yLabel": "337 977" - }, - "category": "Santa Ana", - "y": 337977 - }, - { - "custom": { - "xLabel": "Rodriguez (Montalban)", - "yLabel": "115 167" - }, - "category": "Rodriguez (Montalban)", - "y": 115167 - }, - { - "custom": { - "xLabel": "Mandalay", - "yLabel": "885 300" - }, - "category": "Mandalay", - "y": 885300 - }, - { - "custom": { - "xLabel": "Kenosha", - "yLabel": "89 447" - }, - "category": "Kenosha", - "y": 89447 - }, - { - "custom": { - "xLabel": "Akola", - "yLabel": "328 034" - }, - "category": "Akola", - "y": 328034 - }, - { - "custom": { - "xLabel": "Salatiga", - "yLabel": "103 000" - }, - "category": "Salatiga", - "y": 103000 - }, - { - "custom": { - "xLabel": "Serampore", - "yLabel": "137 028" - }, - "category": "Serampore", - "y": 137028 - }, - { - "custom": { - "xLabel": "Logroño", - "yLabel": "127 093" - }, - "category": "Logroño", - "y": 127093 - }, - { - "custom": { - "xLabel": "Morelia", - "yLabel": "619 958" - }, - "category": "Morelia", - "y": 619958 - }, - { - "custom": { - "xLabel": "Tarija", - "yLabel": "125 255" - }, - "category": "Tarija", - "y": 125255 - }, - { - "custom": { - "xLabel": "Yancheng", - "yLabel": "296 831" - }, - "category": "Yancheng", - "y": 296831 - }, - { - "custom": { - "xLabel": "Hamamatsu", - "yLabel": "568 796" - }, - "category": "Hamamatsu", - "y": 568796 - }, - { - "custom": { - "xLabel": "Jabaliya", - "yLabel": "113 901" - }, - "category": "Jabaliya", - "y": 113901 - }, - { - "custom": { - "xLabel": "Tšernivtsi", - "yLabel": "259 000" - }, - "category": "Tšernivtsi", - "y": 259000 - }, - { - "custom": { - "xLabel": "Nashik (Nasik)", - "yLabel": "656 925" - }, - "category": "Nashik (Nasik)", - "y": 656925 - }, - { - "custom": { - "xLabel": "Barquisimeto", - "yLabel": "877 239" - }, - "category": "Barquisimeto", - "y": 877239 - }, - { - "custom": { - "xLabel": "Krasnodar", - "yLabel": "639 000" - }, - "category": "Krasnodar", - "y": 639000 - }, - { - "custom": { - "xLabel": "Veracruz", - "yLabel": "457 119" - }, - "category": "Veracruz", - "y": 457119 - }, - { - "custom": { - "xLabel": "Oaxaca de Juárez", - "yLabel": "256 848" - }, - "category": "Oaxaca de Juárez", - "y": 256848 - }, - { - "custom": { - "xLabel": "Tejupilco", - "yLabel": "94 934" - }, - "category": "Tejupilco", - "y": 94934 - }, - { - "custom": { - "xLabel": "Yangor", - "yLabel": "4 050" - }, - "category": "Yangor", - "y": 4050 - }, - { - "custom": { - "xLabel": "Van", - "yLabel": "219 319" - }, - "category": "Van", - "y": 219319 - }, - { - "custom": { - "xLabel": "Guantánamo", - "yLabel": "205 078" - }, - "category": "Guantánamo", - "y": 205078 - }, - { - "custom": { - "xLabel": "Masan", - "yLabel": "441 242" - }, - "category": "Masan", - "y": 441242 - }, - { - "custom": { - "xLabel": "Sadiqabad", - "yLabel": "141 500" - }, - "category": "Sadiqabad", - "y": 141500 - }, - { - "custom": { - "xLabel": "Saharanpur", - "yLabel": "374 945" - }, - "category": "Saharanpur", - "y": 374945 - }, - { - "custom": { - "xLabel": "Zhangjiagang", - "yLabel": "97 994" - }, - "category": "Zhangjiagang", - "y": 97994 - }, - { - "custom": { - "xLabel": "Bamenda", - "yLabel": "138 000" - }, - "category": "Bamenda", - "y": 138000 - }, - { - "custom": { - "xLabel": "Kumo", - "yLabel": "148 000" - }, - "category": "Kumo", - "y": 148000 - }, - { - "custom": { - "xLabel": "Cali", - "yLabel": "2 077 386" - }, - "category": "Cali", - "y": 2077386 - }, - { - "custom": { - "xLabel": "Saint Louis", - "yLabel": "348 189" - }, - "category": "Saint Louis", - "y": 348189 - }, - { - "custom": { - "xLabel": "Fresnillo", - "yLabel": "182 744" - }, - "category": "Fresnillo", - "y": 182744 - }, - { - "custom": { - "xLabel": "Lusaka", - "yLabel": "1 317 000" - }, - "category": "Lusaka", - "y": 1317000 - }, - { - "custom": { - "xLabel": "Cimanggis", - "yLabel": "205 100" - }, - "category": "Cimanggis", - "y": 205100 - }, - { - "custom": { - "xLabel": "Abidjan", - "yLabel": "2 500 000" - }, - "category": "Abidjan", - "y": 2500000 - }, - { - "custom": { - "xLabel": "Pleven", - "yLabel": "121 952" - }, - "category": "Pleven", - "y": 121952 - }, - { - "custom": { - "xLabel": "Hama", - "yLabel": "343 361" - }, - "category": "Hama", - "y": 343361 - }, - { - "custom": { - "xLabel": "Jackson", - "yLabel": "184 256" - }, - "category": "Jackson", - "y": 184256 - }, - { - "custom": { - "xLabel": "Medan", - "yLabel": "1 843 919" - }, - "category": "Medan", - "y": 1843919 - }, - { - "custom": { - "xLabel": "Quy Nhon", - "yLabel": "163 385" - }, - "category": "Quy Nhon", - "y": 163385 - }, - { - "custom": { - "xLabel": "Boca del Río", - "yLabel": "135 721" - }, - "category": "Boca del Río", - "y": 135721 - }, - { - "custom": { - "xLabel": "Bulandshahr", - "yLabel": "127 201" - }, - "category": "Bulandshahr", - "y": 127201 - }, - { - "custom": { - "xLabel": "Rampur", - "yLabel": "243 742" - }, - "category": "Rampur", - "y": 243742 - }, - { - "custom": { - "xLabel": "Ilobu", - "yLabel": "199 000" - }, - "category": "Ilobu", - "y": 199000 - }, - { - "custom": { - "xLabel": "Jingdezhen", - "yLabel": "281 183" - }, - "category": "Jingdezhen", - "y": 281183 - }, - { - "custom": { - "xLabel": "Chimbote", - "yLabel": "336 000" - }, - "category": "Chimbote", - "y": 336000 - }, - { - "custom": { - "xLabel": "Leicester", - "yLabel": "294 000" - }, - "category": "Leicester", - "y": 294000 - }, - { - "custom": { - "xLabel": "Bottrop", - "yLabel": "121 097" - }, - "category": "Bottrop", - "y": 121097 - }, - { - "custom": { - "xLabel": "Athens-Clarke County", - "yLabel": "101 489" - }, - "category": "Athens-Clarke County", - "y": 101489 - }, - { - "custom": { - "xLabel": "Eluru", - "yLabel": "212 866" - }, - "category": "Eluru", - "y": 212866 - }, - { - "custom": { - "xLabel": "Kuytun", - "yLabel": "118 553" - }, - "category": "Kuytun", - "y": 118553 - }, - { - "custom": { - "xLabel": "Brownsville", - "yLabel": "139 722" - }, - "category": "Brownsville", - "y": 139722 - }, - { - "custom": { - "xLabel": "San Felipe", - "yLabel": "95 305" - }, - "category": "San Felipe", - "y": 95305 - }, - { - "custom": { - "xLabel": "Olomouc", - "yLabel": "102 702" - }, - "category": "Olomouc", - "y": 102702 - }, - { - "custom": { - "xLabel": "Butembo", - "yLabel": "109 406" - }, - "category": "Butembo", - "y": 109406 - }, - { - "custom": { - "xLabel": "Sullana", - "yLabel": "147 361" - }, - "category": "Sullana", - "y": 147361 - }, - { - "custom": { - "xLabel": "Turmero", - "yLabel": "217 499" - }, - "category": "Turmero", - "y": 217499 - }, - { - "custom": { - "xLabel": "Amagasaki", - "yLabel": "481 434" - }, - "category": "Amagasaki", - "y": 481434 - }, - { - "custom": { - "xLabel": "Purwakarta", - "yLabel": "95 900" - }, - "category": "Purwakarta", - "y": 95900 - }, - { - "custom": { - "xLabel": "Sangju", - "yLabel": "124 116" - }, - "category": "Sangju", - "y": 124116 - }, - { - "custom": { - "xLabel": "Ghulja", - "yLabel": "177 193" - }, - "category": "Ghulja", - "y": 177193 - }, - { - "custom": { - "xLabel": "Tachikawa", - "yLabel": "159 430" - }, - "category": "Tachikawa", - "y": 159430 - }, - { - "custom": { - "xLabel": "Antalya", - "yLabel": "564 914" - }, - "category": "Antalya", - "y": 564914 - }, - { - "custom": { - "xLabel": "Yulin", - "yLabel": "144 467" - }, - "category": "Yulin", - "y": 144467 - }, - { - "custom": { - "xLabel": "Maringá", - "yLabel": "286 461" - }, - "category": "Maringá", - "y": 286461 - }, - { - "custom": { - "xLabel": "Brno", - "yLabel": "381 862" - }, - "category": "Brno", - "y": 381862 - }, - { - "custom": { - "xLabel": "Huaiyin", - "yLabel": "239 675" - }, - "category": "Huaiyin", - "y": 239675 - }, - { - "custom": { - "xLabel": "Ettadhamen", - "yLabel": "178 600" - }, - "category": "Ettadhamen", - "y": 178600 - }, - { - "custom": { - "xLabel": "Odawara", - "yLabel": "200 171" - }, - "category": "Odawara", - "y": 200171 - }, - { - "custom": { - "xLabel": "Koyang", - "yLabel": "518 282" - }, - "category": "Koyang", - "y": 518282 - }, - { - "custom": { - "xLabel": "Birkirkara", - "yLabel": "21 445" - }, - "category": "Birkirkara", - "y": 21445 - }, - { - "custom": { - "xLabel": "São Caetano do Sul", - "yLabel": "133 321" - }, - "category": "São Caetano do Sul", - "y": 133321 - }, - { - "custom": { - "xLabel": "Houston", - "yLabel": "1 953 631" - }, - "category": "Houston", - "y": 1953631 - }, - { - "custom": { - "xLabel": "Gütersloh", - "yLabel": "95 028" - }, - "category": "Gütersloh", - "y": 95028 - }, - { - "custom": { - "xLabel": "Matsudo", - "yLabel": "461 126" - }, - "category": "Matsudo", - "y": 461126 - }, - { - "custom": { - "xLabel": "Antofagasta", - "yLabel": "251 429" - }, - "category": "Antofagasta", - "y": 251429 - }, - { - "custom": { - "xLabel": "Trier", - "yLabel": "99 891" - }, - "category": "Trier", - "y": 99891 - }, - { - "custom": { - "xLabel": "Vigo", - "yLabel": "283 670" - }, - "category": "Vigo", - "y": 283670 - }, - { - "custom": { - "xLabel": "Nagaon", - "yLabel": "93 350" - }, - "category": "Nagaon", - "y": 93350 - }, - { - "custom": { - "xLabel": "al-Sib", - "yLabel": "155 000" - }, - "category": "al-Sib", - "y": 155000 - }, - { - "custom": { - "xLabel": "Calcutta [Kolkata]", - "yLabel": "4 399 819" - }, - "category": "Calcutta [Kolkata]", - "y": 4399819 - }, - { - "custom": { - "xLabel": "Temixco", - "yLabel": "92 686" - }, - "category": "Temixco", - "y": 92686 - }, - { - "custom": { - "xLabel": "Misrata", - "yLabel": "121 669" - }, - "category": "Misrata", - "y": 121669 - }, - { - "custom": { - "xLabel": "Orsk", - "yLabel": "273 900" - }, - "category": "Orsk", - "y": 273900 - }, - { - "custom": { - "xLabel": "Navolato", - "yLabel": "145 396" - }, - "category": "Navolato", - "y": 145396 - }, - { - "custom": { - "xLabel": "Feira de Santana", - "yLabel": "479 992" - }, - "category": "Feira de Santana", - "y": 479992 - }, - { - "custom": { - "xLabel": "Lincoln", - "yLabel": "225 581" - }, - "category": "Lincoln", - "y": 225581 - }, - { - "custom": { - "xLabel": "Xiaogan", - "yLabel": "166 280" - }, - "category": "Xiaogan", - "y": 166280 - }, - { - "custom": { - "xLabel": "Ecatepec de Morelos", - "yLabel": "1 620 303" - }, - "category": "Ecatepec de Morelos", - "y": 1620303 - }, - { - "custom": { - "xLabel": "Navotas", - "yLabel": "230 403" - }, - "category": "Navotas", - "y": 230403 - }, - { - "custom": { - "xLabel": "Sakado", - "yLabel": "98 221" - }, - "category": "Sakado", - "y": 98221 - }, - { - "custom": { - "xLabel": "Ipswich", - "yLabel": "114 000" - }, - "category": "Ipswich", - "y": 114000 - }, - { - "custom": { - "xLabel": "Kishiwada", - "yLabel": "197 276" - }, - "category": "Kishiwada", - "y": 197276 - }, - { - "custom": { - "xLabel": "Kashan", - "yLabel": "201 372" - }, - "category": "Kashan", - "y": 201372 - }, - { - "custom": { - "xLabel": "Hannover", - "yLabel": "514 718" - }, - "category": "Hannover", - "y": 514718 - }, - { - "custom": { - "xLabel": "Pozuelos", - "yLabel": "105 690" - }, - "category": "Pozuelos", - "y": 105690 - }, - { - "custom": { - "xLabel": "Isahaya", - "yLabel": "93 058" - }, - "category": "Isahaya", - "y": 93058 - }, - { - "custom": { - "xLabel": "Kitchener", - "yLabel": "189 959" - }, - "category": "Kitchener", - "y": 189959 - }, - { - "custom": { - "xLabel": "Voronez", - "yLabel": "907 700" - }, - "category": "Voronez", - "y": 907700 - }, - { - "custom": { - "xLabel": "Shulin", - "yLabel": "151 260" - }, - "category": "Shulin", - "y": 151260 - }, - { - "custom": { - "xLabel": "North Dum Dum", - "yLabel": "149 965" - }, - "category": "North Dum Dum", - "y": 149965 - }, - { - "custom": { - "xLabel": "Baku", - "yLabel": "1 787 800" - }, - "category": "Baku", - "y": 1787800 - }, - { - "custom": { - "xLabel": "Stanley", - "yLabel": "1 636" - }, - "category": "Stanley", - "y": 1636 - }, - { - "custom": { - "xLabel": "Coral Springs", - "yLabel": "117 549" - }, - "category": "Coral Springs", - "y": 117549 - }, - { - "custom": { - "xLabel": "Greensboro", - "yLabel": "223 891" - }, - "category": "Greensboro", - "y": 223891 - }, - { - "custom": { - "xLabel": "Dera Ismail Khan", - "yLabel": "90 400" - }, - "category": "Dera Ismail Khan", - "y": 90400 - }, - { - "custom": { - "xLabel": "Guarujá", - "yLabel": "237 206" - }, - "category": "Guarujá", - "y": 237206 - }, - { - "custom": { - "xLabel": "Silao", - "yLabel": "134 037" - }, - "category": "Silao", - "y": 134037 - }, - { - "custom": { - "xLabel": "My Tho", - "yLabel": "108 404" - }, - "category": "My Tho", - "y": 108404 - }, - { - "custom": { - "xLabel": "Oldenburg", - "yLabel": "154 125" - }, - "category": "Oldenburg", - "y": 154125 - }, - { - "custom": { - "xLabel": "Kawachinagano", - "yLabel": "119 666" - }, - "category": "Kawachinagano", - "y": 119666 - }, - { - "custom": { - "xLabel": "Chungli", - "yLabel": "318 649" - }, - "category": "Chungli", - "y": 318649 - }, - { - "custom": { - "xLabel": "Ouagadougou", - "yLabel": "824 000" - }, - "category": "Ouagadougou", - "y": 824000 - }, - { - "custom": { - "xLabel": "Santa Coloma de Gramenet", - "yLabel": "120 802" - }, - "category": "Santa Coloma de Gramenet", - "y": 120802 - }, - { - "custom": { - "xLabel": "Ikoma", - "yLabel": "111 645" - }, - "category": "Ikoma", - "y": 111645 - }, - { - "custom": { - "xLabel": "Gainesville", - "yLabel": "92 291" - }, - "category": "Gainesville", - "y": 92291 - }, - { - "custom": { - "xLabel": "Sivas", - "yLabel": "246 642" - }, - "category": "Sivas", - "y": 246642 - }, - { - "custom": { - "xLabel": "Warren", - "yLabel": "138 247" - }, - "category": "Warren", - "y": 138247 - }, - { - "custom": { - "xLabel": "New Bedford", - "yLabel": "94 780" - }, - "category": "New Bedford", - "y": 94780 - }, - { - "custom": { - "xLabel": "Brest", - "yLabel": "149 634" - }, - "category": "Brest", - "y": 149634 - }, - { - "custom": { - "xLabel": "Zeleznogorsk", - "yLabel": "94 000" - }, - "category": "Zeleznogorsk", - "y": 94000 - }, - { - "custom": { - "xLabel": "Lille", - "yLabel": "184 657" - }, - "category": "Lille", - "y": 184657 - }, - { - "custom": { - "xLabel": "Toskent", - "yLabel": "2 117 500" - }, - "category": "Toskent", - "y": 2117500 - }, - { - "custom": { - "xLabel": "Tuxtla Gutiérrez", - "yLabel": "433 544" - }, - "category": "Tuxtla Gutiérrez", - "y": 433544 - }, - { - "custom": { - "xLabel": "Hino", - "yLabel": "166 770" - }, - "category": "Hino", - "y": 166770 - }, - { - "custom": { - "xLabel": "Gifu", - "yLabel": "408 007" - }, - "category": "Gifu", - "y": 408007 - }, - { - "custom": { - "xLabel": "Pultava [Poltava]", - "yLabel": "313 000" - }, - "category": "Pultava [Poltava]", - "y": 313000 - }, - { - "custom": { - "xLabel": "Palhoça", - "yLabel": "89 465" - }, - "category": "Palhoça", - "y": 89465 - }, - { - "custom": { - "xLabel": "Fagatogo", - "yLabel": "2 323" - }, - "category": "Fagatogo", - "y": 2323 - }, - { - "custom": { - "xLabel": "Luanshya", - "yLabel": "118 100" - }, - "category": "Luanshya", - "y": 118100 - }, - { - "custom": { - "xLabel": "Bankura", - "yLabel": "114 876" - }, - "category": "Bankura", - "y": 114876 - }, - { - "custom": { - "xLabel": "Nkongsamba", - "yLabel": "112 454" - }, - "category": "Nkongsamba", - "y": 112454 - }, - { - "custom": { - "xLabel": "L´Hospitalet de Llobregat", - "yLabel": "247 986" - }, - "category": "L´Hospitalet de Llobregat", - "y": 247986 - }, - { - "custom": { - "xLabel": "Ingraj Bazar (English Bazar)", - "yLabel": "139 204" - }, - "category": "Ingraj Bazar (English Bazar)", - "y": 139204 - }, - { - "custom": { - "xLabel": "Mito", - "yLabel": "246 559" - }, - "category": "Mito", - "y": 246559 - }, - { - "custom": { - "xLabel": "Elblag", - "yLabel": "129 782" - }, - "category": "Elblag", - "y": 129782 - }, - { - "custom": { - "xLabel": "Raurkela", - "yLabel": "215 489" - }, - "category": "Raurkela", - "y": 215489 - }, - { - "custom": { - "xLabel": "Jokohama [Yokohama]", - "yLabel": "3 339 594" - }, - "category": "Jokohama [Yokohama]", - "y": 3339594 - }, - { - "custom": { - "xLabel": "Marv Dasht", - "yLabel": "103 579" - }, - "category": "Marv Dasht", - "y": 103579 - }, - { - "custom": { - "xLabel": "Sylhet", - "yLabel": "117 396" - }, - "category": "Sylhet", - "y": 117396 - }, - { - "custom": { - "xLabel": "Pate", - "yLabel": "161 700" - }, - "category": "Pate", - "y": 161700 - }, - { - "custom": { - "xLabel": "Adoni", - "yLabel": "136 182" - }, - "category": "Adoni", - "y": 136182 - }, - { - "custom": { - "xLabel": "Gazipur", - "yLabel": "96 717" - }, - "category": "Gazipur", - "y": 96717 - }, - { - "custom": { - "xLabel": "South Dum Dum", - "yLabel": "232 811" - }, - "category": "South Dum Dum", - "y": 232811 - }, - { - "custom": { - "xLabel": "Onitsha", - "yLabel": "371 900" - }, - "category": "Onitsha", - "y": 371900 - }, - { - "custom": { - "xLabel": "Samara", - "yLabel": "1 156 100" - }, - "category": "Samara", - "y": 1156100 - }, - { - "custom": { - "xLabel": "Shaki", - "yLabel": "174 500" - }, - "category": "Shaki", - "y": 174500 - }, - { - "custom": { - "xLabel": "Port Harcourt", - "yLabel": "410 000" - }, - "category": "Port Harcourt", - "y": 410000 - }, - { - "custom": { - "xLabel": "Piatra Neamt", - "yLabel": "125 070" - }, - "category": "Piatra Neamt", - "y": 125070 - }, - { - "custom": { - "xLabel": "Hitachinaka", - "yLabel": "148 006" - }, - "category": "Hitachinaka", - "y": 148006 - }, - { - "custom": { - "xLabel": "Scottsdale", - "yLabel": "202 705" - }, - "category": "Scottsdale", - "y": 202705 - }, - { - "custom": { - "xLabel": "Canberra", - "yLabel": "322 723" - }, - "category": "Canberra", - "y": 322723 - }, - { - "custom": { - "xLabel": "Nazilli", - "yLabel": "99 900" - }, - "category": "Nazilli", - "y": 99900 - }, - { - "custom": { - "xLabel": "Klagenfurt", - "yLabel": "91 141" - }, - "category": "Klagenfurt", - "y": 91141 - }, - { - "custom": { - "xLabel": "Gorontalo", - "yLabel": "94 058" - }, - "category": "Gorontalo", - "y": 94058 - }, - { - "custom": { - "xLabel": "Halle/Saale", - "yLabel": "254 360" - }, - "category": "Halle/Saale", - "y": 254360 - }, - { - "custom": { - "xLabel": "San Antonio", - "yLabel": "1 144 646" - }, - "category": "San Antonio", - "y": 1144646 - }, - { - "custom": { - "xLabel": "Cheltenham", - "yLabel": "106 000" - }, - "category": "Cheltenham", - "y": 106000 - }, - { - "custom": { - "xLabel": "Hildesheim", - "yLabel": "104 013" - }, - "category": "Hildesheim", - "y": 104013 - }, - { - "custom": { - "xLabel": "Imabari", - "yLabel": "119 357" - }, - "category": "Imabari", - "y": 119357 - }, - { - "custom": { - "xLabel": "Irvine", - "yLabel": "143 072" - }, - "category": "Irvine", - "y": 143072 - }, - { - "custom": { - "xLabel": "Ahvaz", - "yLabel": "804 980" - }, - "category": "Ahvaz", - "y": 804980 - }, - { - "custom": { - "xLabel": "London", - "yLabel": "7 285 000" - }, - "category": "London", - "y": 7285000 - }, - { - "custom": { - "xLabel": "Quilmes", - "yLabel": "559 249" - }, - "category": "Quilmes", - "y": 559249 - }, - { - "custom": { - "xLabel": "Bangui", - "yLabel": "524 000" - }, - "category": "Bangui", - "y": 524000 - }, - { - "custom": { - "xLabel": "Jalgaon", - "yLabel": "242 193" - }, - "category": "Jalgaon", - "y": 242193 - }, - { - "custom": { - "xLabel": "Fuling", - "yLabel": "173 878" - }, - "category": "Fuling", - "y": 173878 - }, - { - "custom": { - "xLabel": "Zhaoqing", - "yLabel": "194 784" - }, - "category": "Zhaoqing", - "y": 194784 - }, - { - "custom": { - "xLabel": "Sterling Heights", - "yLabel": "124 471" - }, - "category": "Sterling Heights", - "y": 124471 - }, - { - "custom": { - "xLabel": "Biên Hoa", - "yLabel": "282 095" - }, - "category": "Biên Hoa", - "y": 282095 - }, - { - "custom": { - "xLabel": "Sanmenxia", - "yLabel": "120 523" - }, - "category": "Sanmenxia", - "y": 120523 - }, - { - "custom": { - "xLabel": "Sjeverodonetsk", - "yLabel": "127 000" - }, - "category": "Sjeverodonetsk", - "y": 127000 - }, - { - "custom": { - "xLabel": "Nakuru", - "yLabel": "163 927" - }, - "category": "Nakuru", - "y": 163927 - }, - { - "custom": { - "xLabel": "Ulhasnagar", - "yLabel": "369 077" - }, - "category": "Ulhasnagar", - "y": 369077 - }, - { - "custom": { - "xLabel": "Qomsheh", - "yLabel": "89 800" - }, - "category": "Qomsheh", - "y": 89800 - }, - { - "custom": { - "xLabel": "Tatuí", - "yLabel": "93 897" - }, - "category": "Tatuí", - "y": 93897 - }, - { - "custom": { - "xLabel": "Ado-Ekiti", - "yLabel": "359 400" - }, - "category": "Ado-Ekiti", - "y": 359400 - }, - { - "custom": { - "xLabel": "Tambaram", - "yLabel": "107 187" - }, - "category": "Tambaram", - "y": 107187 - }, - { - "custom": { - "xLabel": "Koganei", - "yLabel": "110 969" - }, - "category": "Koganei", - "y": 110969 - }, - { - "custom": { - "xLabel": "Tong-yong", - "yLabel": "131 717" - }, - "category": "Tong-yong", - "y": 131717 - }, - { - "custom": { - "xLabel": "Zelenodolsk", - "yLabel": "100 200" - }, - "category": "Zelenodolsk", - "y": 100200 - }, - { - "custom": { - "xLabel": "Tshikapa", - "yLabel": "180 860" - }, - "category": "Tshikapa", - "y": 180860 - }, - { - "custom": { - "xLabel": "Mit Ghamr", - "yLabel": "101 801" - }, - "category": "Mit Ghamr", - "y": 101801 - }, - { - "custom": { - "xLabel": "Erie", - "yLabel": "103 717" - }, - "category": "Erie", - "y": 103717 - }, - { - "custom": { - "xLabel": "Ikirun", - "yLabel": "181 400" - }, - "category": "Ikirun", - "y": 181400 - }, - { - "custom": { - "xLabel": "Miami Beach", - "yLabel": "97 855" - }, - "category": "Miami Beach", - "y": 97855 - }, - { - "custom": { - "xLabel": "Barcelona", - "yLabel": "1 503 451" - }, - "category": "Barcelona", - "y": 1503451 - }, - { - "custom": { - "xLabel": "Lviv", - "yLabel": "788 000" - }, - "category": "Lviv", - "y": 788000 - }, - { - "custom": { - "xLabel": "Davenport", - "yLabel": "98 256" - }, - "category": "Davenport", - "y": 98256 - }, - { - "custom": { - "xLabel": "Râmnicu Vâlcea", - "yLabel": "119 741" - }, - "category": "Râmnicu Vâlcea", - "y": 119741 - }, - { - "custom": { - "xLabel": "Perugia", - "yLabel": "156 673" - }, - "category": "Perugia", - "y": 156673 - }, - { - "custom": { - "xLabel": "Nuevo Laredo", - "yLabel": "310 277" - }, - "category": "Nuevo Laredo", - "y": 310277 - }, - { - "custom": { - "xLabel": "Khammam", - "yLabel": "127 992" - }, - "category": "Khammam", - "y": 127992 - }, - { - "custom": { - "xLabel": "Bani Suwayf", - "yLabel": "172 032" - }, - "category": "Bani Suwayf", - "y": 172032 - }, - { - "custom": { - "xLabel": "Kaili", - "yLabel": "113 958" - }, - "category": "Kaili", - "y": 113958 - }, - { - "custom": { - "xLabel": "Tenali", - "yLabel": "143 726" - }, - "category": "Tenali", - "y": 143726 - }, - { - "custom": { - "xLabel": "Barinas", - "yLabel": "217 831" - }, - "category": "Barinas", - "y": 217831 - }, - { - "custom": { - "xLabel": "Taichung", - "yLabel": "940 589" - }, - "category": "Taichung", - "y": 940589 - }, - { - "custom": { - "xLabel": "Fujisawa", - "yLabel": "372 840" - }, - "category": "Fujisawa", - "y": 372840 - }, - { - "custom": { - "xLabel": "Chiayi", - "yLabel": "265 109" - }, - "category": "Chiayi", - "y": 265109 - }, - { - "custom": { - "xLabel": "Salamanca", - "yLabel": "158 720" - }, - "category": "Salamanca", - "y": 158720 - }, - { - "custom": { - "xLabel": "Niš", - "yLabel": "175 391" - }, - "category": "Niš", - "y": 175391 - }, - { - "custom": { - "xLabel": "North York", - "yLabel": "622 632" - }, - "category": "North York", - "y": 622632 - }, - { - "custom": { - "xLabel": "Magelang", - "yLabel": "123 800" - }, - "category": "Magelang", - "y": 123800 - }, - { - "custom": { - "xLabel": "Qom", - "yLabel": "777 677" - }, - "category": "Qom", - "y": 777677 - }, - { - "custom": { - "xLabel": "Kuwana", - "yLabel": "106 121" - }, - "category": "Kuwana", - "y": 106121 - }, - { - "custom": { - "xLabel": "Mbuji-Mayi", - "yLabel": "806 475" - }, - "category": "Mbuji-Mayi", - "y": 806475 - }, - { - "custom": { - "xLabel": "Santarém", - "yLabel": "241 771" - }, - "category": "Santarém", - "y": 241771 - }, - { - "custom": { - "xLabel": "Panchiao", - "yLabel": "523 850" - }, - "category": "Panchiao", - "y": 523850 - }, - { - "custom": { - "xLabel": "Mount Darwin", - "yLabel": "164 362" - }, - "category": "Mount Darwin", - "y": 164362 - }, - { - "custom": { - "xLabel": "Yonago", - "yLabel": "136 461" - }, - "category": "Yonago", - "y": 136461 - }, - { - "custom": { - "xLabel": "Wolverhampton", - "yLabel": "242 000" - }, - "category": "Wolverhampton", - "y": 242000 - }, - { - "custom": { - "xLabel": "Guanajuato", - "yLabel": "141 215" - }, - "category": "Guanajuato", - "y": 141215 - }, - { - "custom": { - "xLabel": "Purwokerto", - "yLabel": "202 500" - }, - "category": "Purwokerto", - "y": 202500 - }, - { - "custom": { - "xLabel": "Georgetown", - "yLabel": "254 000" - }, - "category": "Georgetown", - "y": 254000 - }, - { - "custom": { - "xLabel": "Ruda Slaska", - "yLabel": "159 665" - }, - "category": "Ruda Slaska", - "y": 159665 - }, - { - "custom": { - "xLabel": "Savannah", - "yLabel": "131 510" - }, - "category": "Savannah", - "y": 131510 - }, - { - "custom": { - "xLabel": "al-Tuqba", - "yLabel": "125 700" - }, - "category": "al-Tuqba", - "y": 125700 - }, - { - "custom": { - "xLabel": "Tétouan", - "yLabel": "277 516" - }, - "category": "Tétouan", - "y": 277516 - }, - { - "custom": { - "xLabel": "Saint George", - "yLabel": "1 800" - }, - "category": "Saint George", - "y": 1800 - }, - { - "custom": { - "xLabel": "Maradi", - "yLabel": "112 965" - }, - "category": "Maradi", - "y": 112965 - }, - { - "custom": { - "xLabel": "Akita", - "yLabel": "314 440" - }, - "category": "Akita", - "y": 314440 - }, - { - "custom": { - "xLabel": "Burnpur", - "yLabel": "174 933" - }, - "category": "Burnpur", - "y": 174933 - }, - { - "custom": { - "xLabel": "Bugulma", - "yLabel": "94 100" - }, - "category": "Bugulma", - "y": 94100 - }, - { - "custom": { - "xLabel": "Gloucester", - "yLabel": "107 314" - }, - "category": "Gloucester", - "y": 107314 - }, - { - "custom": { - "xLabel": "Rimini", - "yLabel": "131 062" - }, - "category": "Rimini", - "y": 131062 - }, - { - "custom": { - "xLabel": "Arkangeli", - "yLabel": "361 800" - }, - "category": "Arkangeli", - "y": 361800 - }, - { - "custom": { - "xLabel": "Metz", - "yLabel": "123 776" - }, - "category": "Metz", - "y": 123776 - }, - { - "custom": { - "xLabel": "Khamis Mushayt", - "yLabel": "217 900" - }, - "category": "Khamis Mushayt", - "y": 217900 - }, - { - "custom": { - "xLabel": "Ituiutaba", - "yLabel": "90 507" - }, - "category": "Ituiutaba", - "y": 90507 - }, - { - "custom": { - "xLabel": "Montería", - "yLabel": "248 245" - }, - "category": "Montería", - "y": 248245 - }, - { - "custom": { - "xLabel": "Samarkand", - "yLabel": "361 800" - }, - "category": "Samarkand", - "y": 361800 - }, - { - "custom": { - "xLabel": "Porbandar", - "yLabel": "116 671" - }, - "category": "Porbandar", - "y": 116671 - }, - { - "custom": { - "xLabel": "Malmö", - "yLabel": "259 579" - }, - "category": "Malmö", - "y": 259579 - }, - { - "custom": { - "xLabel": "Ota", - "yLabel": "145 317" - }, - "category": "Ota", - "y": 145317 - }, - { - "custom": { - "xLabel": "Bahawalnagar", - "yLabel": "109 600" - }, - "category": "Bahawalnagar", - "y": 109600 - }, - { - "custom": { - "xLabel": "Kayseri", - "yLabel": "475 657" - }, - "category": "Kayseri", - "y": 475657 - }, - { - "custom": { - "xLabel": "Cúcuta", - "yLabel": "606 932" - }, - "category": "Cúcuta", - "y": 606932 - }, - { - "custom": { - "xLabel": "Pagakku (Pakokku)", - "yLabel": "94 800" - }, - "category": "Pagakku (Pakokku)", - "y": 94800 - }, - { - "custom": { - "xLabel": "Talca", - "yLabel": "187 557" - }, - "category": "Talca", - "y": 187557 - }, - { - "custom": { - "xLabel": "Ilhéus", - "yLabel": "254 970" - }, - "category": "Ilhéus", - "y": 254970 - }, - { - "custom": { - "xLabel": "Hobart", - "yLabel": "126 118" - }, - "category": "Hobart", - "y": 126118 - }, - { - "custom": { - "xLabel": "Myingyan", - "yLabel": "103 600" - }, - "category": "Myingyan", - "y": 103600 - }, - { - "custom": { - "xLabel": "Sendai", - "yLabel": "989 975" - }, - "category": "Sendai", - "y": 989975 - }, - { - "custom": { - "xLabel": "San Carlos", - "yLabel": "154 264" - }, - "category": "San Carlos", - "y": 154264 - }, - { - "custom": { - "xLabel": "Caracas", - "yLabel": "1 975 294" - }, - "category": "Caracas", - "y": 1975294 - }, - { - "custom": { - "xLabel": "Minsk", - "yLabel": "1 674 000" - }, - "category": "Minsk", - "y": 1674000 - }, - { - "custom": { - "xLabel": "Simferopol", - "yLabel": "339 000" - }, - "category": "Simferopol", - "y": 339000 - }, - { - "custom": { - "xLabel": "Batman", - "yLabel": "203 793" - }, - "category": "Batman", - "y": 203793 - }, - { - "custom": { - "xLabel": "Hengyang", - "yLabel": "487 148" - }, - "category": "Hengyang", - "y": 487148 - }, - { - "custom": { - "xLabel": "Faizabad", - "yLabel": "124 437" - }, - "category": "Faizabad", - "y": 124437 - }, - { - "custom": { - "xLabel": "Huntsville", - "yLabel": "158 216" - }, - "category": "Huntsville", - "y": 158216 - }, - { - "custom": { - "xLabel": "Huimanguillo", - "yLabel": "158 335" - }, - "category": "Huimanguillo", - "y": 158335 - }, - { - "custom": { - "xLabel": "Ciudad del Este", - "yLabel": "133 881" - }, - "category": "Ciudad del Este", - "y": 133881 - }, - { - "custom": { - "xLabel": "Luxor", - "yLabel": "360 503" - }, - "category": "Luxor", - "y": 360503 - }, - { - "custom": { - "xLabel": "Kaiyuan", - "yLabel": "91 999" - }, - "category": "Kaiyuan", - "y": 91999 - }, - { - "custom": { - "xLabel": "Alor Setar", - "yLabel": "124 412" - }, - "category": "Alor Setar", - "y": 124412 - }, - { - "custom": { - "xLabel": "Maribor", - "yLabel": "115 532" - }, - "category": "Maribor", - "y": 115532 - }, - { - "custom": { - "xLabel": "Anshun", - "yLabel": "174 142" - }, - "category": "Anshun", - "y": 174142 - }, - { - "custom": { - "xLabel": "Moscow", - "yLabel": "8 389 200" - }, - "category": "Moscow", - "y": 8389200 - }, - { - "custom": { - "xLabel": "Pikine", - "yLabel": "855 287" - }, - "category": "Pikine", - "y": 855287 - }, - { - "custom": { - "xLabel": "Quevedo", - "yLabel": "129 631" - }, - "category": "Quevedo", - "y": 129631 - }, - { - "custom": { - "xLabel": "Dijon", - "yLabel": "149 867" - }, - "category": "Dijon", - "y": 149867 - }, - { - "custom": { - "xLabel": "Chandigarh", - "yLabel": "504 094" - }, - "category": "Chandigarh", - "y": 504094 - }, - { - "custom": { - "xLabel": "Dunedin", - "yLabel": "119 600" - }, - "category": "Dunedin", - "y": 119600 - }, - { - "custom": { - "xLabel": "Durgapur", - "yLabel": "425 836" - }, - "category": "Durgapur", - "y": 425836 - }, - { - "custom": { - "xLabel": "Liu´an", - "yLabel": "144 248" - }, - "category": "Liu´an", - "y": 144248 - }, - { - "custom": { - "xLabel": "Surigao", - "yLabel": "118 534" - }, - "category": "Surigao", - "y": 118534 - }, - { - "custom": { - "xLabel": "Sitapur", - "yLabel": "121 842" - }, - "category": "Sitapur", - "y": 121842 - }, - { - "custom": { - "xLabel": "Tultitlán", - "yLabel": "432 411" - }, - "category": "Tultitlán", - "y": 432411 - }, - { - "custom": { - "xLabel": "Hunjiang", - "yLabel": "482 043" - }, - "category": "Hunjiang", - "y": 482043 - }, - { - "custom": { - "xLabel": "Heyuan", - "yLabel": "120 101" - }, - "category": "Heyuan", - "y": 120101 - }, - { - "custom": { - "xLabel": "Napoli", - "yLabel": "1 002 619" - }, - "category": "Napoli", - "y": 1002619 - }, - { - "custom": { - "xLabel": "Pinsk", - "yLabel": "130 000" - }, - "category": "Pinsk", - "y": 130000 - }, - { - "custom": { - "xLabel": "Macuspana", - "yLabel": "133 795" - }, - "category": "Macuspana", - "y": 133795 - }, - { - "custom": { - "xLabel": "Pemalang", - "yLabel": "103 500" - }, - "category": "Pemalang", - "y": 103500 - }, - { - "custom": { - "xLabel": "Binjai", - "yLabel": "127 222" - }, - "category": "Binjai", - "y": 127222 - }, - { - "custom": { - "xLabel": "Charleroi", - "yLabel": "200 827" - }, - "category": "Charleroi", - "y": 200827 - }, - { - "custom": { - "xLabel": "Amravati", - "yLabel": "421 576" - }, - "category": "Amravati", - "y": 421576 - }, - { - "custom": { - "xLabel": "Kuri", - "yLabel": "142 173" - }, - "category": "Kuri", - "y": 142173 - }, - { - "custom": { - "xLabel": "al-Rusayfa", - "yLabel": "137 247" - }, - "category": "al-Rusayfa", - "y": 137247 - }, - { - "custom": { - "xLabel": "Saransk", - "yLabel": "314 800" - }, - "category": "Saransk", - "y": 314800 - }, - { - "custom": { - "xLabel": "Matsubara", - "yLabel": "135 010" - }, - "category": "Matsubara", - "y": 135010 - }, - { - "custom": { - "xLabel": "Ozamis", - "yLabel": "110 420" - }, - "category": "Ozamis", - "y": 110420 - }, - { - "custom": { - "xLabel": "Sohumi", - "yLabel": "111 700" - }, - "category": "Sohumi", - "y": 111700 - }, - { - "custom": { - "xLabel": "Bayambang", - "yLabel": "96 609" - }, - "category": "Bayambang", - "y": 96609 - }, - { - "custom": { - "xLabel": "Jixi", - "yLabel": "683 885" - }, - "category": "Jixi", - "y": 683885 - }, - { - "custom": { - "xLabel": "Maxixe", - "yLabel": "93 985" - }, - "category": "Maxixe", - "y": 93985 - }, - { - "custom": { - "xLabel": "Dzerzinsk", - "yLabel": "277 100" - }, - "category": "Dzerzinsk", - "y": 277100 - }, - { - "custom": { - "xLabel": "Angra dos Reis", - "yLabel": "96 864" - }, - "category": "Angra dos Reis", - "y": 96864 - }, - { - "custom": { - "xLabel": "Koshigaya", - "yLabel": "301 446" - }, - "category": "Koshigaya", - "y": 301446 - }, - { - "custom": { - "xLabel": "Springfield", - "yLabel": "151 580" - }, - "category": "Springfield", - "y": 151580 - }, - { - "custom": { - "xLabel": "Allappuzha (Alleppey)", - "yLabel": "174 666" - }, - "category": "Allappuzha (Alleppey)", - "y": 174666 - }, - { - "custom": { - "xLabel": "Santa Rosa", - "yLabel": "147 595" - }, - "category": "Santa Rosa", - "y": 147595 - }, - { - "custom": { - "xLabel": "Hamhung", - "yLabel": "709 730" - }, - "category": "Hamhung", - "y": 709730 - }, - { - "custom": { - "xLabel": "Chongqing", - "yLabel": "6 351 600" - }, - "category": "Chongqing", - "y": 6351600 - }, - { - "custom": { - "xLabel": "Sirajganj", - "yLabel": "99 669" - }, - "category": "Sirajganj", - "y": 99669 - }, - { - "custom": { - "xLabel": "Cajamarca", - "yLabel": "108 009" - }, - "category": "Cajamarca", - "y": 108009 - }, - { - "custom": { - "xLabel": "Badalona", - "yLabel": "209 635" - }, - "category": "Badalona", - "y": 209635 - }, - { - "custom": { - "xLabel": "Bihar Sharif", - "yLabel": "201 323" - }, - "category": "Bihar Sharif", - "y": 201323 - }, - { - "custom": { - "xLabel": "Comilla", - "yLabel": "135 313" - }, - "category": "Comilla", - "y": 135313 - }, - { - "custom": { - "xLabel": "Petroskoi", - "yLabel": "282 100" - }, - "category": "Petroskoi", - "y": 282100 - }, - { - "custom": { - "xLabel": "Chillán", - "yLabel": "178 182" - }, - "category": "Chillán", - "y": 178182 - }, - { - "custom": { - "xLabel": "Dehra Dun", - "yLabel": "270 159" - }, - "category": "Dehra Dun", - "y": 270159 - }, - { - "custom": { - "xLabel": "Palma de Mallorca", - "yLabel": "326 993" - }, - "category": "Palma de Mallorca", - "y": 326993 - }, - { - "custom": { - "xLabel": "Saint Helier", - "yLabel": "27 523" - }, - "category": "Saint Helier", - "y": 27523 - }, - { - "custom": { - "xLabel": "Aguascalientes", - "yLabel": "643 360" - }, - "category": "Aguascalientes", - "y": 643360 - }, - { - "custom": { - "xLabel": "Joškar-Ola", - "yLabel": "249 200" - }, - "category": "Joškar-Ola", - "y": 249200 - }, - { - "custom": { - "xLabel": "Elgin", - "yLabel": "89 408" - }, - "category": "Elgin", - "y": 89408 - }, - { - "custom": { - "xLabel": "Albacete", - "yLabel": "147 527" - }, - "category": "Albacete", - "y": 147527 - }, - { - "custom": { - "xLabel": "Pesaro", - "yLabel": "88 987" - }, - "category": "Pesaro", - "y": 88987 - }, - { - "custom": { - "xLabel": "Málaga", - "yLabel": "530 553" - }, - "category": "Málaga", - "y": 530553 - }, - { - "custom": { - "xLabel": "San José", - "yLabel": "339 131" - }, - "category": "San José", - "y": 339131 - }, - { - "custom": { - "xLabel": "Kamagaya", - "yLabel": "100 821" - }, - "category": "Kamagaya", - "y": 100821 - }, - { - "custom": { - "xLabel": "Mérida", - "yLabel": "703 324" - }, - "category": "Mérida", - "y": 703324 - }, - { - "custom": { - "xLabel": "Higashimatsuyama", - "yLabel": "93 342" - }, - "category": "Higashimatsuyama", - "y": 93342 - }, - { - "custom": { - "xLabel": "Adiyaman", - "yLabel": "141 529" - }, - "category": "Adiyaman", - "y": 141529 - }, - { - "custom": { - "xLabel": "Mandi Bahauddin", - "yLabel": "97 300" - }, - "category": "Mandi Bahauddin", - "y": 97300 - }, - { - "custom": { - "xLabel": "Amoy [Xiamen]", - "yLabel": "627 500" - }, - "category": "Amoy [Xiamen]", - "y": 627500 - }, - { - "custom": { - "xLabel": "Oka-Akoko", - "yLabel": "142 900" - }, - "category": "Oka-Akoko", - "y": 142900 - }, - { - "custom": { - "xLabel": "Nagaoka", - "yLabel": "192 407" - }, - "category": "Nagaoka", - "y": 192407 - }, - { - "custom": { - "xLabel": "Gudivada", - "yLabel": "101 656" - }, - "category": "Gudivada", - "y": 101656 - }, - { - "custom": { - "xLabel": "San Juan", - "yLabel": "434 374" - }, - "category": "San Juan", - "y": 434374 - }, - { - "custom": { - "xLabel": "Mohammedia", - "yLabel": "154 706" - }, - "category": "Mohammedia", - "y": 154706 - }, - { - "custom": { - "xLabel": "Akashi", - "yLabel": "292 253" - }, - "category": "Akashi", - "y": 292253 - }, - { - "custom": { - "xLabel": "Pomona", - "yLabel": "149 473" - }, - "category": "Pomona", - "y": 149473 - }, - { - "custom": { - "xLabel": "Amadora", - "yLabel": "122 106" - }, - "category": "Amadora", - "y": 122106 - }, - { - "custom": { - "xLabel": "Latur", - "yLabel": "197 408" - }, - "category": "Latur", - "y": 197408 - }, - { - "custom": { - "xLabel": "Solapur (Sholapur)", - "yLabel": "604 215" - }, - "category": "Solapur (Sholapur)", - "y": 604215 - }, - { - "custom": { - "xLabel": "Wuhai", - "yLabel": "264 081" - }, - "category": "Wuhai", - "y": 264081 - }, - { - "custom": { - "xLabel": "Monterrey", - "yLabel": "1 108 499" - }, - "category": "Monterrey", - "y": 1108499 - }, - { - "custom": { - "xLabel": "Ekibastuz", - "yLabel": "127 200" - }, - "category": "Ekibastuz", - "y": 127200 - }, - { - "custom": { - "xLabel": "Yamaguchi", - "yLabel": "138 210" - }, - "category": "Yamaguchi", - "y": 138210 - }, - { - "custom": { - "xLabel": "Rajkot", - "yLabel": "559 407" - }, - "category": "Rajkot", - "y": 559407 - }, - { - "custom": { - "xLabel": "Calabozo", - "yLabel": "107 146" - }, - "category": "Calabozo", - "y": 107146 - }, - { - "custom": { - "xLabel": "Laohekou", - "yLabel": "123 366" - }, - "category": "Laohekou", - "y": 123366 - }, - { - "custom": { - "xLabel": "Dayton", - "yLabel": "166 179" - }, - "category": "Dayton", - "y": 166179 - }, - { - "custom": { - "xLabel": "Meru", - "yLabel": "94 947" - }, - "category": "Meru", - "y": 94947 - }, - { - "custom": { - "xLabel": "Purulia", - "yLabel": "92 574" - }, - "category": "Purulia", - "y": 92574 - }, - { - "custom": { - "xLabel": "Puebla", - "yLabel": "1 346 176" - }, - "category": "Puebla", - "y": 1346176 - }, - { - "custom": { - "xLabel": "Tunis", - "yLabel": "690 600" - }, - "category": "Tunis", - "y": 690600 - }, - { - "custom": { - "xLabel": "Bridgetown", - "yLabel": "6 070" - }, - "category": "Bridgetown", - "y": 6070 - }, - { - "custom": { - "xLabel": "Mdantsane", - "yLabel": "182 639" - }, - "category": "Mdantsane", - "y": 182639 - }, - { - "custom": { - "xLabel": "Raichur", - "yLabel": "157 551" - }, - "category": "Raichur", - "y": 157551 - }, - { - "custom": { - "xLabel": "Hyderabad", - "yLabel": "2 964 638" - }, - "category": "Hyderabad", - "y": 2964638 - }, - { - "custom": { - "xLabel": "Tafuna", - "yLabel": "5 200" - }, - "category": "Tafuna", - "y": 5200 - }, - { - "custom": { - "xLabel": "Chincha Alta", - "yLabel": "110 016" - }, - "category": "Chincha Alta", - "y": 110016 - }, - { - "custom": { - "xLabel": "Pardubice", - "yLabel": "91 309" - }, - "category": "Pardubice", - "y": 91309 - }, - { - "custom": { - "xLabel": "Yuyao", - "yLabel": "114 065" - }, - "category": "Yuyao", - "y": 114065 - }, - { - "custom": { - "xLabel": "Parnaíba", - "yLabel": "129 756" - }, - "category": "Parnaíba", - "y": 129756 - }, - { - "custom": { - "xLabel": "Obihiro", - "yLabel": "173 685" - }, - "category": "Obihiro", - "y": 173685 - }, - { - "custom": { - "xLabel": "Pangkal Pinang", - "yLabel": "124 000" - }, - "category": "Pangkal Pinang", - "y": 124000 - }, - { - "custom": { - "xLabel": "San Cristóbal", - "yLabel": "319 373" - }, - "category": "San Cristóbal", - "y": 319373 - }, - { - "custom": { - "xLabel": "Nanded (Nander)", - "yLabel": "275 083" - }, - "category": "Nanded (Nander)", - "y": 275083 - }, - { - "custom": { - "xLabel": "West Bromwich", - "yLabel": "146 386" - }, - "category": "West Bromwich", - "y": 146386 - }, - { - "custom": { - "xLabel": "Yangzhou", - "yLabel": "312 892" - }, - "category": "Yangzhou", - "y": 312892 - }, - { - "custom": { - "xLabel": "Hailun", - "yLabel": "133 565" - }, - "category": "Hailun", - "y": 133565 - }, - { - "custom": { - "xLabel": "Garoua", - "yLabel": "177 000" - }, - "category": "Garoua", - "y": 177000 - }, - { - "custom": { - "xLabel": "Urumtši [Ürümqi]", - "yLabel": "1 310 100" - }, - "category": "Urumtši [Ürümqi]", - "y": 1310100 - }, - { - "custom": { - "xLabel": "Odense", - "yLabel": "183 912" - }, - "category": "Odense", - "y": 183912 - }, - { - "custom": { - "xLabel": "Zhumadian", - "yLabel": "123 232" - }, - "category": "Zhumadian", - "y": 123232 - }, - { - "custom": { - "xLabel": "Brovary", - "yLabel": "89 000" - }, - "category": "Brovary", - "y": 89000 - }, - { - "custom": { - "xLabel": "København", - "yLabel": "495 699" - }, - "category": "København", - "y": 495699 - }, - { - "custom": { - "xLabel": "Salamanca", - "yLabel": "226 864" - }, - "category": "Salamanca", - "y": 226864 - }, - { - "custom": { - "xLabel": "Altševsk", - "yLabel": "119 000" - }, - "category": "Altševsk", - "y": 119000 - }, - { - "custom": { - "xLabel": "Lipetsk", - "yLabel": "521 000" - }, - "category": "Lipetsk", - "y": 521000 - }, - { - "custom": { - "xLabel": "Tobolsk", - "yLabel": "97 600" - }, - "category": "Tobolsk", - "y": 97600 - }, - { - "custom": { - "xLabel": "Ahmadpur East", - "yLabel": "96 000" - }, - "category": "Ahmadpur East", - "y": 96000 - }, - { - "custom": { - "xLabel": "Kanpur Cantonment", - "yLabel": "93 109" - }, - "category": "Kanpur Cantonment", - "y": 93109 - }, - { - "custom": { - "xLabel": "Las Heras", - "yLabel": "145 823" - }, - "category": "Las Heras", - "y": 145823 - }, - { - "custom": { - "xLabel": "Tórshavn", - "yLabel": "14 542" - }, - "category": "Tórshavn", - "y": 14542 - }, - { - "custom": { - "xLabel": "Khanpur", - "yLabel": "117 800" - }, - "category": "Khanpur", - "y": 117800 - }, - { - "custom": { - "xLabel": "Varginha", - "yLabel": "108 314" - }, - "category": "Varginha", - "y": 108314 - }, - { - "custom": { - "xLabel": "Asyut", - "yLabel": "343 498" - }, - "category": "Asyut", - "y": 343498 - }, - { - "custom": { - "xLabel": "Semarang", - "yLabel": "1 104 405" - }, - "category": "Semarang", - "y": 1104405 - }, - { - "custom": { - "xLabel": "Oberhausen", - "yLabel": "222 349" - }, - "category": "Oberhausen", - "y": 222349 - }, - { - "custom": { - "xLabel": "Potosí", - "yLabel": "140 642" - }, - "category": "Potosí", - "y": 140642 - }, - { - "custom": { - "xLabel": "Nagpur", - "yLabel": "1 624 752" - }, - "category": "Nagpur", - "y": 1624752 - }, - { - "custom": { - "xLabel": "Santiago de Cuba", - "yLabel": "433 180" - }, - "category": "Santiago de Cuba", - "y": 433180 - }, - { - "custom": { - "xLabel": "Jinchang", - "yLabel": "105 287" - }, - "category": "Jinchang", - "y": 105287 - }, - { - "custom": { - "xLabel": "Bellevue", - "yLabel": "109 569" - }, - "category": "Bellevue", - "y": 109569 - }, - { - "custom": { - "xLabel": "Newcastle", - "yLabel": "222 993" - }, - "category": "Newcastle", - "y": 222993 - }, - { - "custom": { - "xLabel": "Cotonou", - "yLabel": "536 827" - }, - "category": "Cotonou", - "y": 536827 - }, - { - "custom": { - "xLabel": "Zama", - "yLabel": "122 046" - }, - "category": "Zama", - "y": 122046 - }, - { - "custom": { - "xLabel": "Jaworzno", - "yLabel": "97 929" - }, - "category": "Jaworzno", - "y": 97929 - }, - { - "custom": { - "xLabel": "Mwene-Ditu", - "yLabel": "137 459" - }, - "category": "Mwene-Ditu", - "y": 137459 - }, - { - "custom": { - "xLabel": "Bayugan", - "yLabel": "93 623" - }, - "category": "Bayugan", - "y": 93623 - }, - { - "custom": { - "xLabel": "Pindamonhangaba", - "yLabel": "121 904" - }, - "category": "Pindamonhangaba", - "y": 121904 - }, - { - "custom": { - "xLabel": "Kirikkale", - "yLabel": "142 044" - }, - "category": "Kirikkale", - "y": 142044 - }, - { - "custom": { - "xLabel": "Malabon", - "yLabel": "338 855" - }, - "category": "Malabon", - "y": 338855 - }, - { - "custom": { - "xLabel": "Rajapalaiyam", - "yLabel": "114 202" - }, - "category": "Rajapalaiyam", - "y": 114202 - }, - { - "custom": { - "xLabel": "Caruaru", - "yLabel": "244 247" - }, - "category": "Caruaru", - "y": 244247 - }, - { - "custom": { - "xLabel": "Bucuresti", - "yLabel": "2 016 131" - }, - "category": "Bucuresti", - "y": 2016131 - }, - { - "custom": { - "xLabel": "Klin", - "yLabel": "90 000" - }, - "category": "Klin", - "y": 90000 - }, - { - "custom": { - "xLabel": "Ismailia", - "yLabel": "254 477" - }, - "category": "Ismailia", - "y": 254477 - }, - { - "custom": { - "xLabel": "Norwalk", - "yLabel": "103 298" - }, - "category": "Norwalk", - "y": 103298 - }, - { - "custom": { - "xLabel": "Jönköping", - "yLabel": "117 095" - }, - "category": "Jönköping", - "y": 117095 - }, - { - "custom": { - "xLabel": "Odintsovo", - "yLabel": "127 400" - }, - "category": "Odintsovo", - "y": 127400 - }, - { - "custom": { - "xLabel": "Qods", - "yLabel": "138 278" - }, - "category": "Qods", - "y": 138278 - }, - { - "custom": { - "xLabel": "Kameoka", - "yLabel": "92 398" - }, - "category": "Kameoka", - "y": 92398 - }, - { - "custom": { - "xLabel": "Târgu Mures", - "yLabel": "165 153" - }, - "category": "Târgu Mures", - "y": 165153 - }, - { - "custom": { - "xLabel": "Marabá", - "yLabel": "167 795" - }, - "category": "Marabá", - "y": 167795 - }, - { - "custom": { - "xLabel": "Emeishan", - "yLabel": "94 000" - }, - "category": "Emeishan", - "y": 94000 - }, - { - "custom": { - "xLabel": "Ceyhan", - "yLabel": "102 412" - }, - "category": "Ceyhan", - "y": 102412 - }, - { - "custom": { - "xLabel": "Pinhais", - "yLabel": "98 198" - }, - "category": "Pinhais", - "y": 98198 - }, - { - "custom": { - "xLabel": "Fortaleza", - "yLabel": "2 097 757" - }, - "category": "Fortaleza", - "y": 2097757 - }, - { - "custom": { - "xLabel": "Mashhad", - "yLabel": "1 887 405" - }, - "category": "Mashhad", - "y": 1887405 - }, - { - "custom": { - "xLabel": "Polomolok", - "yLabel": "110 709" - }, - "category": "Polomolok", - "y": 110709 - }, - { - "custom": { - "xLabel": "Longyearbyen", - "yLabel": "1 438" - }, - "category": "Longyearbyen", - "y": 1438 - }, - { - "custom": { - "xLabel": "Belém", - "yLabel": "1 186 926" - }, - "category": "Belém", - "y": 1186926 - }, - { - "custom": { - "xLabel": "Santo Domingo de los Colorados", - "yLabel": "202 111" - }, - "category": "Santo Domingo de los Colorados", - "y": 202111 - }, - { - "custom": { - "xLabel": "Lerma", - "yLabel": "99 714" - }, - "category": "Lerma", - "y": 99714 - }, - { - "custom": { - "xLabel": "Viransehir", - "yLabel": "106 400" - }, - "category": "Viransehir", - "y": 106400 - }, - { - "custom": { - "xLabel": "Izmit (Kocaeli)", - "yLabel": "210 068" - }, - "category": "Izmit (Kocaeli)", - "y": 210068 - }, - { - "custom": { - "xLabel": "Herne", - "yLabel": "175 661" - }, - "category": "Herne", - "y": 175661 - }, - { - "custom": { - "xLabel": "Nampula", - "yLabel": "303 346" - }, - "category": "Nampula", - "y": 303346 - }, - { - "custom": { - "xLabel": "Cheju", - "yLabel": "258 511" - }, - "category": "Cheju", - "y": 258511 - }, - { - "custom": { - "xLabel": "Cagayan de Oro", - "yLabel": "461 877" - }, - "category": "Cagayan de Oro", - "y": 461877 - }, - { - "custom": { - "xLabel": "Uberaba", - "yLabel": "249 225" - }, - "category": "Uberaba", - "y": 249225 - }, - { - "custom": { - "xLabel": "San Felipe del Progreso", - "yLabel": "177 330" - }, - "category": "San Felipe del Progreso", - "y": 177330 - }, - { - "custom": { - "xLabel": "Kiseljovsk", - "yLabel": "110 000" - }, - "category": "Kiseljovsk", - "y": 110000 - }, - { - "custom": { - "xLabel": "Bhind", - "yLabel": "109 755" - }, - "category": "Bhind", - "y": 109755 - }, - { - "custom": { - "xLabel": "Frankfurt am Main", - "yLabel": "643 821" - }, - "category": "Frankfurt am Main", - "y": 643821 - }, - { - "custom": { - "xLabel": "Surabaya", - "yLabel": "2 663 820" - }, - "category": "Surabaya", - "y": 2663820 - }, - { - "custom": { - "xLabel": "Baton Rouge", - "yLabel": "227 818" - }, - "category": "Baton Rouge", - "y": 227818 - }, - { - "custom": { - "xLabel": "Sincelejo", - "yLabel": "220 704" - }, - "category": "Sincelejo", - "y": 220704 - }, - { - "custom": { - "xLabel": "Jiutai", - "yLabel": "180 130" - }, - "category": "Jiutai", - "y": 180130 - }, - { - "custom": { - "xLabel": "Chapra", - "yLabel": "136 877" - }, - "category": "Chapra", - "y": 136877 - }, - { - "custom": { - "xLabel": "Malang", - "yLabel": "716 862" - }, - "category": "Malang", - "y": 716862 - }, - { - "custom": { - "xLabel": "Douala", - "yLabel": "1 448 300" - }, - "category": "Douala", - "y": 1448300 - }, - { - "custom": { - "xLabel": "Sobral", - "yLabel": "146 005" - }, - "category": "Sobral", - "y": 146005 - }, - { - "custom": { - "xLabel": "Inazawa", - "yLabel": "98 746" - }, - "category": "Inazawa", - "y": 98746 - }, - { - "custom": { - "xLabel": "Eskisehir", - "yLabel": "470 781" - }, - "category": "Eskisehir", - "y": 470781 - }, - { - "custom": { - "xLabel": "Kadoma", - "yLabel": "138 953" - }, - "category": "Kadoma", - "y": 138953 - }, - { - "custom": { - "xLabel": "Yichun", - "yLabel": "151 585" - }, - "category": "Yichun", - "y": 151585 - }, - { - "custom": { - "xLabel": "Paris", - "yLabel": "2 125 246" - }, - "category": "Paris", - "y": 2125246 - }, - { - "custom": { - "xLabel": "Banha", - "yLabel": "145 792" - }, - "category": "Banha", - "y": 145792 - }, - { - "custom": { - "xLabel": "Zalantun", - "yLabel": "130 031" - }, - "category": "Zalantun", - "y": 130031 - }, - { - "custom": { - "xLabel": "Newark", - "yLabel": "273 546" - }, - "category": "Newark", - "y": 273546 - }, - { - "custom": { - "xLabel": "Bacau", - "yLabel": "209 235" - }, - "category": "Bacau", - "y": 209235 - }, - { - "custom": { - "xLabel": "Ichinomiya", - "yLabel": "270 828" - }, - "category": "Ichinomiya", - "y": 270828 - }, - { - "custom": { - "xLabel": "Cardiff", - "yLabel": "321 000" - }, - "category": "Cardiff", - "y": 321000 - }, - { - "custom": { - "xLabel": "Sakura", - "yLabel": "168 072" - }, - "category": "Sakura", - "y": 168072 - }, - { - "custom": { - "xLabel": "Sambhal", - "yLabel": "150 869" - }, - "category": "Sambhal", - "y": 150869 - }, - { - "custom": { - "xLabel": "Cárdenas", - "yLabel": "216 903" - }, - "category": "Cárdenas", - "y": 216903 - }, - { - "custom": { - "xLabel": "Champdani", - "yLabel": "98 818" - }, - "category": "Champdani", - "y": 98818 - }, - { - "custom": { - "xLabel": "Wonju", - "yLabel": "237 460" - }, - "category": "Wonju", - "y": 237460 - }, - { - "custom": { - "xLabel": "Sarajevo", - "yLabel": "360 000" - }, - "category": "Sarajevo", - "y": 360000 - }, - { - "custom": { - "xLabel": "Katsina", - "yLabel": "206 500" - }, - "category": "Katsina", - "y": 206500 - }, - { - "custom": { - "xLabel": "Cádiz", - "yLabel": "142 449" - }, - "category": "Cádiz", - "y": 142449 - }, - { - "custom": { - "xLabel": "Haora (Howrah)", - "yLabel": "950 435" - }, - "category": "Haora (Howrah)", - "y": 950435 - }, - { - "custom": { - "xLabel": "Guangyuan", - "yLabel": "182 241" - }, - "category": "Guangyuan", - "y": 182241 - }, - { - "custom": { - "xLabel": "Mataró", - "yLabel": "104 095" - }, - "category": "Mataró", - "y": 104095 - }, - { - "custom": { - "xLabel": "Catania", - "yLabel": "337 862" - }, - "category": "Catania", - "y": 337862 - }, - { - "custom": { - "xLabel": "Erzincan", - "yLabel": "102 304" - }, - "category": "Erzincan", - "y": 102304 - }, - { - "custom": { - "xLabel": "Solikamsk", - "yLabel": "106 000" - }, - "category": "Solikamsk", - "y": 106000 - }, - { - "custom": { - "xLabel": "Tecomán", - "yLabel": "99 296" - }, - "category": "Tecomán", - "y": 99296 - }, - { - "custom": { - "xLabel": "Tongliao", - "yLabel": "255 129" - }, - "category": "Tongliao", - "y": 255129 - }, - { - "custom": { - "xLabel": "Nouméa", - "yLabel": "76 293" - }, - "category": "Nouméa", - "y": 76293 - }, - { - "custom": { - "xLabel": "Henderson", - "yLabel": "175 381" - }, - "category": "Henderson", - "y": 175381 - }, - { - "custom": { - "xLabel": "Tres de Febrero", - "yLabel": "352 311" - }, - "category": "Tres de Febrero", - "y": 352311 - }, - { - "custom": { - "xLabel": "´s-Hertogenbosch", - "yLabel": "129 170" - }, - "category": "´s-Hertogenbosch", - "y": 129170 - }, - { - "custom": { - "xLabel": "Las Margaritas", - "yLabel": "97 389" - }, - "category": "Las Margaritas", - "y": 97389 - }, - { - "custom": { - "xLabel": "Benito Juárez", - "yLabel": "419 276" - }, - "category": "Benito Juárez", - "y": 419276 - }, - { - "custom": { - "xLabel": "Varamin", - "yLabel": "107 233" - }, - "category": "Varamin", - "y": 107233 - }, - { - "custom": { - "xLabel": "Hebron", - "yLabel": "119 401" - }, - "category": "Hebron", - "y": 119401 - }, - { - "custom": { - "xLabel": "Calgary", - "yLabel": "768 082" - }, - "category": "Calgary", - "y": 768082 - }, - { - "custom": { - "xLabel": "Compton", - "yLabel": "92 864" - }, - "category": "Compton", - "y": 92864 - }, - { - "custom": { - "xLabel": "Hong Gai", - "yLabel": "127 484" - }, - "category": "Hong Gai", - "y": 127484 - }, - { - "custom": { - "xLabel": "Poryong", - "yLabel": "122 604" - }, - "category": "Poryong", - "y": 122604 - }, - { - "custom": { - "xLabel": "Vitoria-Gasteiz", - "yLabel": "217 154" - }, - "category": "Vitoria-Gasteiz", - "y": 217154 - }, - { - "custom": { - "xLabel": "Lages", - "yLabel": "139 570" - }, - "category": "Lages", - "y": 139570 - }, - { - "custom": { - "xLabel": "Malegaon", - "yLabel": "342 595" - }, - "category": "Malegaon", - "y": 342595 - }, - { - "custom": { - "xLabel": "Resita", - "yLabel": "93 976" - }, - "category": "Resita", - "y": 93976 - }, - { - "custom": { - "xLabel": "El Mante", - "yLabel": "112 453" - }, - "category": "El Mante", - "y": 112453 - }, - { - "custom": { - "xLabel": "Ashoknagar-Kalyangarh", - "yLabel": "96 315" - }, - "category": "Ashoknagar-Kalyangarh", - "y": 96315 - }, - { - "custom": { - "xLabel": "Francisco Morato", - "yLabel": "121 197" - }, - "category": "Francisco Morato", - "y": 121197 - }, - { - "custom": { - "xLabel": "Kariya", - "yLabel": "127 969" - }, - "category": "Kariya", - "y": 127969 - }, - { - "custom": { - "xLabel": "Leganés", - "yLabel": "173 163" - }, - "category": "Leganés", - "y": 173163 - }, - { - "custom": { - "xLabel": "Foz do Iguaçu", - "yLabel": "259 425" - }, - "category": "Foz do Iguaçu", - "y": 259425 - }, - { - "custom": { - "xLabel": "Nuku´alofa", - "yLabel": "22 400" - }, - "category": "Nuku´alofa", - "y": 22400 - }, - { - "custom": { - "xLabel": "Rio de Janeiro", - "yLabel": "5 598 953" - }, - "category": "Rio de Janeiro", - "y": 5598953 - }, - { - "custom": { - "xLabel": "Neijiang", - "yLabel": "256 012" - }, - "category": "Neijiang", - "y": 256012 - }, - { - "custom": { - "xLabel": "Virginia Beach", - "yLabel": "425 257" - }, - "category": "Virginia Beach", - "y": 425257 - }, - { - "custom": { - "xLabel": "Potsdam", - "yLabel": "128 983" - }, - "category": "Potsdam", - "y": 128983 - }, - { - "custom": { - "xLabel": "Oakland", - "yLabel": "399 484" - }, - "category": "Oakland", - "y": 399484 - }, - { - "custom": { - "xLabel": "Tanjung Pinang", - "yLabel": "89 900" - }, - "category": "Tanjung Pinang", - "y": 89900 - }, - { - "custom": { - "xLabel": "Huadian", - "yLabel": "175 873" - }, - "category": "Huadian", - "y": 175873 - }, - { - "custom": { - "xLabel": "Weno", - "yLabel": "22 000" - }, - "category": "Weno", - "y": 22000 - }, - { - "custom": { - "xLabel": "West Island", - "yLabel": "167" - }, - "category": "West Island", - "y": 167 - }, - { - "custom": { - "xLabel": "Albany", - "yLabel": "93 994" - }, - "category": "Albany", - "y": 93994 - }, - { - "custom": { - "xLabel": "Pécs", - "yLabel": "157 332" - }, - "category": "Pécs", - "y": 157332 - }, - { - "custom": { - "xLabel": "Tšerepovets", - "yLabel": "324 400" - }, - "category": "Tšerepovets", - "y": 324400 - }, - { - "custom": { - "xLabel": "Novokuibyševsk", - "yLabel": "116 200" - }, - "category": "Novokuibyševsk", - "y": 116200 - }, - { - "custom": { - "xLabel": "Overland Park", - "yLabel": "149 080" - }, - "category": "Overland Park", - "y": 149080 - }, - { - "custom": { - "xLabel": "Novotšerkassk", - "yLabel": "184 400" - }, - "category": "Novotšerkassk", - "y": 184400 - }, - { - "custom": { - "xLabel": "Yuci", - "yLabel": "191 356" - }, - "category": "Yuci", - "y": 191356 - }, - { - "custom": { - "xLabel": "Kwang-yang", - "yLabel": "122 052" - }, - "category": "Kwang-yang", - "y": 122052 - }, - { - "custom": { - "xLabel": "Huambo", - "yLabel": "163 100" - }, - "category": "Huambo", - "y": 163100 - }, - { - "custom": { - "xLabel": "Hengshui", - "yLabel": "104 269" - }, - "category": "Hengshui", - "y": 104269 - }, - { - "custom": { - "xLabel": "Kimberley", - "yLabel": "197 254" - }, - "category": "Kimberley", - "y": 197254 - }, - { - "custom": { - "xLabel": "Guaymas", - "yLabel": "130 108" - }, - "category": "Guaymas", - "y": 130108 - }, - { - "custom": { - "xLabel": "Najafabad", - "yLabel": "178 498" - }, - "category": "Najafabad", - "y": 178498 - }, - { - "custom": { - "xLabel": "Waterbury", - "yLabel": "107 271" - }, - "category": "Waterbury", - "y": 107271 - }, - { - "custom": { - "xLabel": "León", - "yLabel": "123 865" - }, - "category": "León", - "y": 123865 - }, - { - "custom": { - "xLabel": "Najran", - "yLabel": "91 000" - }, - "category": "Najran", - "y": 91000 - }, - { - "custom": { - "xLabel": "Xiangtan", - "yLabel": "441 968" - }, - "category": "Xiangtan", - "y": 441968 - }, - { - "custom": { - "xLabel": "Pematang Siantar", - "yLabel": "203 056" - }, - "category": "Pematang Siantar", - "y": 203056 - }, - { - "custom": { - "xLabel": "Cairns", - "yLabel": "92 273" - }, - "category": "Cairns", - "y": 92273 - }, - { - "custom": { - "xLabel": "Papantla", - "yLabel": "170 123" - }, - "category": "Papantla", - "y": 170123 - }, - { - "custom": { - "xLabel": "Ise", - "yLabel": "101 732" - }, - "category": "Ise", - "y": 101732 - }, - { - "custom": { - "xLabel": "Novokuznetsk", - "yLabel": "561 600" - }, - "category": "Novokuznetsk", - "y": 561600 - }, - { - "custom": { - "xLabel": "Kolwezi", - "yLabel": "417 810" - }, - "category": "Kolwezi", - "y": 417810 - }, - { - "custom": { - "xLabel": "Bielsko-Biala", - "yLabel": "180 307" - }, - "category": "Bielsko-Biala", - "y": 180307 - }, - { - "custom": { - "xLabel": "Jining", - "yLabel": "265 248" - }, - "category": "Jining", - "y": 265248 - }, - { - "custom": { - "xLabel": "Macaé", - "yLabel": "125 597" - }, - "category": "Macaé", - "y": 125597 - }, - { - "custom": { - "xLabel": "Washington", - "yLabel": "572 059" - }, - "category": "Washington", - "y": 572059 - }, - { - "custom": { - "xLabel": "Izumisano", - "yLabel": "92 583" - }, - "category": "Izumisano", - "y": 92583 - }, - { - "custom": { - "xLabel": "Higashimurayama", - "yLabel": "136 970" - }, - "category": "Higashimurayama", - "y": 136970 - }, - { - "custom": { - "xLabel": "Chigasaki", - "yLabel": "216 015" - }, - "category": "Chigasaki", - "y": 216015 - }, - { - "custom": { - "xLabel": "Berazategui", - "yLabel": "276 916" - }, - "category": "Berazategui", - "y": 276916 - }, - { - "custom": { - "xLabel": "Gombe", - "yLabel": "107 800" - }, - "category": "Gombe", - "y": 107800 - }, - { - "custom": { - "xLabel": "Babol", - "yLabel": "158 346" - }, - "category": "Babol", - "y": 158346 - }, - { - "custom": { - "xLabel": "Moga", - "yLabel": "108 304" - }, - "category": "Moga", - "y": 108304 - }, - { - "custom": { - "xLabel": "Tokuyama", - "yLabel": "107 078" - }, - "category": "Tokuyama", - "y": 107078 - }, - { - "custom": { - "xLabel": "Blumenau", - "yLabel": "244 379" - }, - "category": "Blumenau", - "y": 244379 - }, - { - "custom": { - "xLabel": "Laizhou", - "yLabel": "198 664" - }, - "category": "Laizhou", - "y": 198664 - }, - { - "custom": { - "xLabel": "Novosibirsk", - "yLabel": "1 398 800" - }, - "category": "Novosibirsk", - "y": 1398800 - }, - { - "custom": { - "xLabel": "Warraq al-Arab", - "yLabel": "127 108" - }, - "category": "Warraq al-Arab", - "y": 127108 - }, - { - "custom": { - "xLabel": "Klerksdorp", - "yLabel": "261 911" - }, - "category": "Klerksdorp", - "y": 261911 - }, - { - "custom": { - "xLabel": "Tandil", - "yLabel": "91 101" - }, - "category": "Tandil", - "y": 91101 - }, - { - "custom": { - "xLabel": "Tepic", - "yLabel": "305 025" - }, - "category": "Tepic", - "y": 305025 - }, - { - "custom": { - "xLabel": "Balti", - "yLabel": "153 400" - }, - "category": "Balti", - "y": 153400 - }, - { - "custom": { - "xLabel": "San Rafael", - "yLabel": "94 651" - }, - "category": "San Rafael", - "y": 94651 - }, - { - "custom": { - "xLabel": "Stahanov", - "yLabel": "101 000" - }, - "category": "Stahanov", - "y": 101000 - }, - { - "custom": { - "xLabel": "Mazatlán", - "yLabel": "380 265" - }, - "category": "Mazatlán", - "y": 380265 - }, - { - "custom": { - "xLabel": "Pointe-Noire", - "yLabel": "500 000" - }, - "category": "Pointe-Noire", - "y": 500000 - }, - { - "custom": { - "xLabel": "Kassala", - "yLabel": "234 622" - }, - "category": "Kassala", - "y": 234622 - }, - { - "custom": { - "xLabel": "Surrey", - "yLabel": "304 477" - }, - "category": "Surrey", - "y": 304477 - }, - { - "custom": { - "xLabel": "Avellaneda", - "yLabel": "353 046" - }, - "category": "Avellaneda", - "y": 353046 - }, - { - "custom": { - "xLabel": "Takasaki", - "yLabel": "239 124" - }, - "category": "Takasaki", - "y": 239124 - }, - { - "custom": { - "xLabel": "Boa Vista", - "yLabel": "167 185" - }, - "category": "Boa Vista", - "y": 167185 - }, - { - "custom": { - "xLabel": "San Pedro Cholula", - "yLabel": "99 734" - }, - "category": "San Pedro Cholula", - "y": 99734 - }, - { - "custom": { - "xLabel": "Walbrzych", - "yLabel": "136 923" - }, - "category": "Walbrzych", - "y": 136923 - }, - { - "custom": { - "xLabel": "Marseille", - "yLabel": "798 430" - }, - "category": "Marseille", - "y": 798430 - }, - { - "custom": { - "xLabel": "Murwara (Katni)", - "yLabel": "163 431" - }, - "category": "Murwara (Katni)", - "y": 163431 - }, - { - "custom": { - "xLabel": "al-Taif", - "yLabel": "416 100" - }, - "category": "al-Taif", - "y": 416100 - }, - { - "custom": { - "xLabel": "Tacna", - "yLabel": "215 683" - }, - "category": "Tacna", - "y": 215683 - }, - { - "custom": { - "xLabel": "Nicosia", - "yLabel": "195 000" - }, - "category": "Nicosia", - "y": 195000 - }, - { - "custom": { - "xLabel": "Haag", - "yLabel": "440 900" - }, - "category": "Haag", - "y": 440900 - }, - { - "custom": { - "xLabel": "Road Town", - "yLabel": "8 000" - }, - "category": "Road Town", - "y": 8000 - }, - { - "custom": { - "xLabel": "Sheikhupura", - "yLabel": "271 875" - }, - "category": "Sheikhupura", - "y": 271875 - }, - { - "custom": { - "xLabel": "Phyongsong", - "yLabel": "272 934" - }, - "category": "Phyongsong", - "y": 272934 - }, - { - "custom": { - "xLabel": "Düsseldorf", - "yLabel": "568 855" - }, - "category": "Düsseldorf", - "y": 568855 - }, - { - "custom": { - "xLabel": "Baguio", - "yLabel": "252 386" - }, - "category": "Baguio", - "y": 252386 - }, - { - "custom": { - "xLabel": "Ixtapaluca", - "yLabel": "293 160" - }, - "category": "Ixtapaluca", - "y": 293160 - }, - { - "custom": { - "xLabel": "Thousand Oaks", - "yLabel": "117 005" - }, - "category": "Thousand Oaks", - "y": 117005 - }, - { - "custom": { - "xLabel": "al-Manama", - "yLabel": "148 000" - }, - "category": "al-Manama", - "y": 148000 - }, - { - "custom": { - "xLabel": "Durham", - "yLabel": "187 035" - }, - "category": "Durham", - "y": 187035 - }, - { - "custom": { - "xLabel": "Morena", - "yLabel": "147 124" - }, - "category": "Morena", - "y": 147124 - }, - { - "custom": { - "xLabel": "Leiden", - "yLabel": "117 196" - }, - "category": "Leiden", - "y": 117196 - }, - { - "custom": { - "xLabel": "San Bernardino", - "yLabel": "185 401" - }, - "category": "San Bernardino", - "y": 185401 - }, - { - "custom": { - "xLabel": "Tokat", - "yLabel": "99 500" - }, - "category": "Tokat", - "y": 99500 - }, - { - "custom": { - "xLabel": "Kimchon", - "yLabel": "147 027" - }, - "category": "Kimchon", - "y": 147027 - }, - { - "custom": { - "xLabel": "Scarborough", - "yLabel": "594 501" - }, - "category": "Scarborough", - "y": 594501 - }, - { - "custom": { - "xLabel": "Anyang", - "yLabel": "591 106" - }, - "category": "Anyang", - "y": 591106 - }, - { - "custom": { - "xLabel": "Frederiksberg", - "yLabel": "90 327" - }, - "category": "Frederiksberg", - "y": 90327 - }, - { - "custom": { - "xLabel": "Turku [Åbo]", - "yLabel": "172 561" - }, - "category": "Turku [Åbo]", - "y": 172561 - }, - { - "custom": { - "xLabel": "San Mateo", - "yLabel": "91 799" - }, - "category": "San Mateo", - "y": 91799 - }, - { - "custom": { - "xLabel": "Florianópolis", - "yLabel": "281 928" - }, - "category": "Florianópolis", - "y": 281928 - }, - { - "custom": { - "xLabel": "Machakos", - "yLabel": "116 293" - }, - "category": "Machakos", - "y": 116293 - }, - { - "custom": { - "xLabel": "Imphal", - "yLabel": "198 535" - }, - "category": "Imphal", - "y": 198535 - }, - { - "custom": { - "xLabel": "Dagupan", - "yLabel": "130 328" - }, - "category": "Dagupan", - "y": 130328 - }, - { - "custom": { - "xLabel": "Oktjabrski", - "yLabel": "111 500" - }, - "category": "Oktjabrski", - "y": 111500 - }, - { - "custom": { - "xLabel": "Jacareí", - "yLabel": "170 356" - }, - "category": "Jacareí", - "y": 170356 - }, - { - "custom": { - "xLabel": "Rajahmundry", - "yLabel": "324 851" - }, - "category": "Rajahmundry", - "y": 324851 - }, - { - "custom": { - "xLabel": "Burgas", - "yLabel": "195 255" - }, - "category": "Burgas", - "y": 195255 - }, - { - "custom": { - "xLabel": "Banyuwangi", - "yLabel": "89 900" - }, - "category": "Banyuwangi", - "y": 89900 - }, - { - "custom": { - "xLabel": "Flint", - "yLabel": "124 943" - }, - "category": "Flint", - "y": 124943 - }, - { - "custom": { - "xLabel": "Maputo", - "yLabel": "1 018 938" - }, - "category": "Maputo", - "y": 1018938 - }, - { - "custom": { - "xLabel": "Tieling", - "yLabel": "254 842" - }, - "category": "Tieling", - "y": 254842 - }, - { - "custom": { - "xLabel": "Reggio di Calabria", - "yLabel": "179 617" - }, - "category": "Reggio di Calabria", - "y": 179617 - }, - { - "custom": { - "xLabel": "Oruro", - "yLabel": "223 553" - }, - "category": "Oruro", - "y": 223553 - }, - { - "custom": { - "xLabel": "Prešov", - "yLabel": "93 977" - }, - "category": "Prešov", - "y": 93977 - }, - { - "custom": { - "xLabel": "Bender (Tîghina)", - "yLabel": "125 700" - }, - "category": "Bender (Tîghina)", - "y": 125700 - }, - { - "custom": { - "xLabel": "Cilacap", - "yLabel": "206 900" - }, - "category": "Cilacap", - "y": 206900 - }, - { - "custom": { - "xLabel": "Kirkuk", - "yLabel": "418 624" - }, - "category": "Kirkuk", - "y": 418624 - }, - { - "custom": { - "xLabel": "Odessa", - "yLabel": "89 293" - }, - "category": "Odessa", - "y": 89293 - }, - { - "custom": { - "xLabel": "Mons", - "yLabel": "90 935" - }, - "category": "Mons", - "y": 90935 - }, - { - "custom": { - "xLabel": "Pabna", - "yLabel": "103 277" - }, - "category": "Pabna", - "y": 103277 - }, - { - "custom": { - "xLabel": "Maturín", - "yLabel": "319 726" - }, - "category": "Maturín", - "y": 319726 - }, - { - "custom": { - "xLabel": "San Martín Texmelucan", - "yLabel": "121 093" - }, - "category": "San Martín Texmelucan", - "y": 121093 - }, - { - "custom": { - "xLabel": "Khorramshahr", - "yLabel": "105 636" - }, - "category": "Khorramshahr", - "y": 105636 - }, - { - "custom": { - "xLabel": "Tuguegarao", - "yLabel": "120 645" - }, - "category": "Tuguegarao", - "y": 120645 - }, - { - "custom": { - "xLabel": "Ovalle", - "yLabel": "94 854" - }, - "category": "Ovalle", - "y": 94854 - }, - { - "custom": { - "xLabel": "Porto Velho", - "yLabel": "309 750" - }, - "category": "Porto Velho", - "y": 309750 - }, - { - "custom": { - "xLabel": "Roanoke", - "yLabel": "93 357" - }, - "category": "Roanoke", - "y": 93357 - }, - { - "custom": { - "xLabel": "Iwakuni", - "yLabel": "106 647" - }, - "category": "Iwakuni", - "y": 106647 - }, - { - "custom": { - "xLabel": "Niznekamsk", - "yLabel": "223 400" - }, - "category": "Niznekamsk", - "y": 223400 - }, - { - "custom": { - "xLabel": "Eslamshahr", - "yLabel": "265 450" - }, - "category": "Eslamshahr", - "y": 265450 - }, - { - "custom": { - "xLabel": "Governador Valadares", - "yLabel": "231 724" - }, - "category": "Governador Valadares", - "y": 231724 - }, - { - "custom": { - "xLabel": "Mwanza", - "yLabel": "172 300" - }, - "category": "Mwanza", - "y": 172300 - }, - { - "custom": { - "xLabel": "Indianapolis", - "yLabel": "791 926" - }, - "category": "Indianapolis", - "y": 791926 - }, - { - "custom": { - "xLabel": "Rewa", - "yLabel": "128 981" - }, - "category": "Rewa", - "y": 128981 - }, - { - "custom": { - "xLabel": "Port Elizabeth", - "yLabel": "752 319" - }, - "category": "Port Elizabeth", - "y": 752319 - }, - { - "custom": { - "xLabel": "Windhoek", - "yLabel": "169 000" - }, - "category": "Windhoek", - "y": 169000 - }, - { - "custom": { - "xLabel": "Berezniki", - "yLabel": "181 900" - }, - "category": "Berezniki", - "y": 181900 - }, - { - "custom": { - "xLabel": "Des Moines", - "yLabel": "198 682" - }, - "category": "Des Moines", - "y": 198682 - }, - { - "custom": { - "xLabel": "Xiantao", - "yLabel": "222 884" - }, - "category": "Xiantao", - "y": 222884 - }, - { - "custom": { - "xLabel": "Yangquan", - "yLabel": "362 268" - }, - "category": "Yangquan", - "y": 362268 - }, - { - "custom": { - "xLabel": "Sterlitamak", - "yLabel": "265 200" - }, - "category": "Sterlitamak", - "y": 265200 - }, - { - "custom": { - "xLabel": "Rostock", - "yLabel": "203 279" - }, - "category": "Rostock", - "y": 203279 - }, - { - "custom": { - "xLabel": "Chinhae", - "yLabel": "125 997" - }, - "category": "Chinhae", - "y": 125997 - }, - { - "custom": { - "xLabel": "Burhanpur", - "yLabel": "172 710" - }, - "category": "Burhanpur", - "y": 172710 - }, - { - "custom": { - "xLabel": "Goma", - "yLabel": "109 094" - }, - "category": "Goma", - "y": 109094 - }, - { - "custom": { - "xLabel": "Conselheiro Lafaiete", - "yLabel": "97 507" - }, - "category": "Conselheiro Lafaiete", - "y": 97507 - }, - { - "custom": { - "xLabel": "Kanchrapara", - "yLabel": "100 194" - }, - "category": "Kanchrapara", - "y": 100194 - }, - { - "custom": { - "xLabel": "Adana", - "yLabel": "1 131 198" - }, - "category": "Adana", - "y": 1131198 - }, - { - "custom": { - "xLabel": "Xianyang", - "yLabel": "352 125" - }, - "category": "Xianyang", - "y": 352125 - }, - { - "custom": { - "xLabel": "Enshi", - "yLabel": "93 056" - }, - "category": "Enshi", - "y": 93056 - }, - { - "custom": { - "xLabel": "Ikeda", - "yLabel": "102 710" - }, - "category": "Ikeda", - "y": 102710 - }, - { - "custom": { - "xLabel": "Las Palmas de Gran Canaria", - "yLabel": "354 757" - }, - "category": "Las Palmas de Gran Canaria", - "y": 354757 - }, - { - "custom": { - "xLabel": "Corrientes", - "yLabel": "258 103" - }, - "category": "Corrientes", - "y": 258103 - }, - { - "custom": { - "xLabel": "Oulu", - "yLabel": "120 753" - }, - "category": "Oulu", - "y": 120753 - }, - { - "custom": { - "xLabel": "Pavlodar", - "yLabel": "300 500" - }, - "category": "Pavlodar", - "y": 300500 - }, - { - "custom": { - "xLabel": "Andimeshk", - "yLabel": "106 923" - }, - "category": "Andimeshk", - "y": 106923 - }, - { - "custom": { - "xLabel": "Nadiad", - "yLabel": "167 051" - }, - "category": "Nadiad", - "y": 167051 - }, - { - "custom": { - "xLabel": "Alkmaar", - "yLabel": "92 713" - }, - "category": "Alkmaar", - "y": 92713 - }, - { - "custom": { - "xLabel": "Malkajgiri", - "yLabel": "126 066" - }, - "category": "Malkajgiri", - "y": 126066 - }, - { - "custom": { - "xLabel": "Köln", - "yLabel": "962 507" - }, - "category": "Köln", - "y": 962507 - }, - { - "custom": { - "xLabel": "Guarapuava", - "yLabel": "160 510" - }, - "category": "Guarapuava", - "y": 160510 - }, - { - "custom": { - "xLabel": "Asunción", - "yLabel": "557 776" - }, - "category": "Asunción", - "y": 557776 - }, - { - "custom": { - "xLabel": "Yatsushiro", - "yLabel": "107 661" - }, - "category": "Yatsushiro", - "y": 107661 - }, - { - "custom": { - "xLabel": "Niterói", - "yLabel": "459 884" - }, - "category": "Niterói", - "y": 459884 - }, - { - "custom": { - "xLabel": "Phoenix", - "yLabel": "1 321 045" - }, - "category": "Phoenix", - "y": 1321045 - }, - { - "custom": { - "xLabel": "Pimpri-Chinchwad", - "yLabel": "517 083" - }, - "category": "Pimpri-Chinchwad", - "y": 517083 - }, - { - "custom": { - "xLabel": "Huzhou", - "yLabel": "218 071" - }, - "category": "Huzhou", - "y": 218071 - }, - { - "custom": { - "xLabel": "Petropavl", - "yLabel": "203 500" - }, - "category": "Petropavl", - "y": 203500 - }, - { - "custom": { - "xLabel": "Bielefeld", - "yLabel": "321 125" - }, - "category": "Bielefeld", - "y": 321125 - }, - { - "custom": { - "xLabel": "al-Qatif", - "yLabel": "98 900" - }, - "category": "al-Qatif", - "y": 98900 - }, - { - "custom": { - "xLabel": "Lubumbashi", - "yLabel": "851 381" - }, - "category": "Lubumbashi", - "y": 851381 - }, - { - "custom": { - "xLabel": "Budapest", - "yLabel": "1 811 552" - }, - "category": "Budapest", - "y": 1811552 - }, - { - "custom": { - "xLabel": "Nizamabad", - "yLabel": "241 034" - }, - "category": "Nizamabad", - "y": 241034 - }, - { - "custom": { - "xLabel": "Abha", - "yLabel": "112 300" - }, - "category": "Abha", - "y": 112300 - }, - { - "custom": { - "xLabel": "Moradabad", - "yLabel": "429 214" - }, - "category": "Moradabad", - "y": 429214 - }, - { - "custom": { - "xLabel": "Cuautla", - "yLabel": "153 132" - }, - "category": "Cuautla", - "y": 153132 - }, - { - "custom": { - "xLabel": "Dasmariñas", - "yLabel": "379 520" - }, - "category": "Dasmariñas", - "y": 379520 - }, - { - "custom": { - "xLabel": "Santa Clara", - "yLabel": "102 361" - }, - "category": "Santa Clara", - "y": 102361 - }, - { - "custom": { - "xLabel": "Xintai", - "yLabel": "281 248" - }, - "category": "Xintai", - "y": 281248 - }, - { - "custom": { - "xLabel": "Franco da Rocha", - "yLabel": "108 964" - }, - "category": "Franco da Rocha", - "y": 108964 - }, - { - "custom": { - "xLabel": "Quanzhou", - "yLabel": "185 154" - }, - "category": "Quanzhou", - "y": 185154 - }, - { - "custom": { - "xLabel": "Los Teques", - "yLabel": "178 784" - }, - "category": "Los Teques", - "y": 178784 - }, - { - "custom": { - "xLabel": "Sorsogon", - "yLabel": "92 512" - }, - "category": "Sorsogon", - "y": 92512 - }, - { - "custom": { - "xLabel": "Sassari", - "yLabel": "120 803" - }, - "category": "Sassari", - "y": 120803 - }, - { - "custom": { - "xLabel": "Kökshetau", - "yLabel": "123 400" - }, - "category": "Kökshetau", - "y": 123400 - }, - { - "custom": { - "xLabel": "Adamstown", - "yLabel": "42" - }, - "category": "Adamstown", - "y": 42 - }, - { - "custom": { - "xLabel": "Anaheim", - "yLabel": "328 014" - }, - "category": "Anaheim", - "y": 328014 - }, - { - "custom": { - "xLabel": "Saint Petersburg", - "yLabel": "248 232" - }, - "category": "Saint Petersburg", - "y": 248232 - }, - { - "custom": { - "xLabel": "Arayat", - "yLabel": "101 792" - }, - "category": "Arayat", - "y": 101792 - }, - { - "custom": { - "xLabel": "Tultepec", - "yLabel": "93 364" - }, - "category": "Tultepec", - "y": 93364 - }, - { - "custom": { - "xLabel": "Thanjavur", - "yLabel": "202 013" - }, - "category": "Thanjavur", - "y": 202013 - }, - { - "custom": { - "xLabel": "Carúpano", - "yLabel": "119 639" - }, - "category": "Carúpano", - "y": 119639 - }, - { - "custom": { - "xLabel": "Brescia", - "yLabel": "191 317" - }, - "category": "Brescia", - "y": 191317 - }, - { - "custom": { - "xLabel": "Reading", - "yLabel": "148 000" - }, - "category": "Reading", - "y": 148000 - }, - { - "custom": { - "xLabel": "Martínez de la Torre", - "yLabel": "118 815" - }, - "category": "Martínez de la Torre", - "y": 118815 - }, - { - "custom": { - "xLabel": "Orai", - "yLabel": "98 640" - }, - "category": "Orai", - "y": 98640 - }, - { - "custom": { - "xLabel": "Kingstown", - "yLabel": "17 100" - }, - "category": "Kingstown", - "y": 17100 - }, - { - "custom": { - "xLabel": "Northampton", - "yLabel": "196 000" - }, - "category": "Northampton", - "y": 196000 - }, - { - "custom": { - "xLabel": "Portsmouth", - "yLabel": "190 000" - }, - "category": "Portsmouth", - "y": 190000 - }, - { - "custom": { - "xLabel": "Nador", - "yLabel": "112 450" - }, - "category": "Nador", - "y": 112450 - }, - { - "custom": { - "xLabel": "Pilar", - "yLabel": "113 428" - }, - "category": "Pilar", - "y": 113428 - }, - { - "custom": { - "xLabel": "Utsunomiya", - "yLabel": "440 353" - }, - "category": "Utsunomiya", - "y": 440353 - }, - { - "custom": { - "xLabel": "Tarnów", - "yLabel": "121 494" - }, - "category": "Tarnów", - "y": 121494 - }, - { - "custom": { - "xLabel": "Karbala", - "yLabel": "296 705" - }, - "category": "Karbala", - "y": 296705 - }, - { - "custom": { - "xLabel": "Faisalabad", - "yLabel": "1 977 246" - }, - "category": "Faisalabad", - "y": 1977246 - }, - { - "custom": { - "xLabel": "Monywa", - "yLabel": "138 600" - }, - "category": "Monywa", - "y": 138600 - }, - { - "custom": { - "xLabel": "Rubtsovsk", - "yLabel": "162 600" - }, - "category": "Rubtsovsk", - "y": 162600 - }, - { - "custom": { - "xLabel": "Ikerre", - "yLabel": "244 600" - }, - "category": "Ikerre", - "y": 244600 - }, - { - "custom": { - "xLabel": "Shizuoka", - "yLabel": "473 854" - }, - "category": "Shizuoka", - "y": 473854 - }, - { - "custom": { - "xLabel": "Coquitlam", - "yLabel": "101 820" - }, - "category": "Coquitlam", - "y": 101820 - }, - { - "custom": { - "xLabel": "Padova", - "yLabel": "211 391" - }, - "category": "Padova", - "y": 211391 - }, - { - "custom": { - "xLabel": "La Rioja", - "yLabel": "138 117" - }, - "category": "La Rioja", - "y": 138117 - }, - { - "custom": { - "xLabel": "Rancho Cucamonga", - "yLabel": "127 743" - }, - "category": "Rancho Cucamonga", - "y": 127743 - }, - { - "custom": { - "xLabel": "Huainan", - "yLabel": "700 000" - }, - "category": "Huainan", - "y": 700000 - }, - { - "custom": { - "xLabel": "Allentown", - "yLabel": "106 632" - }, - "category": "Allentown", - "y": 106632 - }, - { - "custom": { - "xLabel": "Rybnik", - "yLabel": "144 582" - }, - "category": "Rybnik", - "y": 144582 - }, - { - "custom": { - "xLabel": "Geelong", - "yLabel": "125 382" - }, - "category": "Geelong", - "y": 125382 - }, - { - "custom": { - "xLabel": "Castries", - "yLabel": "2 301" - }, - "category": "Castries", - "y": 2301 - }, - { - "custom": { - "xLabel": "Naperville", - "yLabel": "128 358" - }, - "category": "Naperville", - "y": 128358 - }, - { - "custom": { - "xLabel": "Korhogo", - "yLabel": "109 445" - }, - "category": "Korhogo", - "y": 109445 - }, - { - "custom": { - "xLabel": "Taizz", - "yLabel": "317 600" - }, - "category": "Taizz", - "y": 317600 - }, - { - "custom": { - "xLabel": "Tumen", - "yLabel": "91 471" - }, - "category": "Tumen", - "y": 91471 - }, - { - "custom": { - "xLabel": "Zhangzhou", - "yLabel": "181 424" - }, - "category": "Zhangzhou", - "y": 181424 - }, - { - "custom": { - "xLabel": "Muroran", - "yLabel": "108 275" - }, - "category": "Muroran", - "y": 108275 - }, - { - "custom": { - "xLabel": "Shreveport", - "yLabel": "200 145" - }, - "category": "Shreveport", - "y": 200145 - }, - { - "custom": { - "xLabel": "Khartum", - "yLabel": "947 483" - }, - "category": "Khartum", - "y": 947483 - }, - { - "custom": { - "xLabel": "Da´an", - "yLabel": "138 963" - }, - "category": "Da´an", - "y": 138963 - }, - { - "custom": { - "xLabel": "Aparecida de Goiânia", - "yLabel": "324 662" - }, - "category": "Aparecida de Goiânia", - "y": 324662 - }, - { - "custom": { - "xLabel": "Hisar (Hissar)", - "yLabel": "172 677" - }, - "category": "Hisar (Hissar)", - "y": 172677 - }, - { - "custom": { - "xLabel": "Kochi", - "yLabel": "324 710" - }, - "category": "Kochi", - "y": 324710 - }, - { - "custom": { - "xLabel": "Sioux Falls", - "yLabel": "123 975" - }, - "category": "Sioux Falls", - "y": 123975 - }, - { - "custom": { - "xLabel": "Numazu", - "yLabel": "211 382" - }, - "category": "Numazu", - "y": 211382 - }, - { - "custom": { - "xLabel": "Uman", - "yLabel": "90 000" - }, - "category": "Uman", - "y": 90000 - }, - { - "custom": { - "xLabel": "Linköping", - "yLabel": "133 168" - }, - "category": "Linköping", - "y": 133168 - }, - { - "custom": { - "xLabel": "Varanasi (Benares)", - "yLabel": "929 270" - }, - "category": "Varanasi (Benares)", - "y": 929270 - }, - { - "custom": { - "xLabel": "Ibarra", - "yLabel": "130 643" - }, - "category": "Ibarra", - "y": 130643 - }, - { - "custom": { - "xLabel": "Durango", - "yLabel": "490 524" - }, - "category": "Durango", - "y": 490524 - }, - { - "custom": { - "xLabel": "Chenzhou", - "yLabel": "169 400" - }, - "category": "Chenzhou", - "y": 169400 - }, - { - "custom": { - "xLabel": "Ajmer", - "yLabel": "402 700" - }, - "category": "Ajmer", - "y": 402700 - }, - { - "custom": { - "xLabel": "Betim", - "yLabel": "302 108" - }, - "category": "Betim", - "y": 302108 - }, - { - "custom": { - "xLabel": "Santa Monica", - "yLabel": "91 084" - }, - "category": "Santa Monica", - "y": 91084 - }, - { - "custom": { - "xLabel": "Nampo", - "yLabel": "566 200" - }, - "category": "Nampo", - "y": 566200 - }, - { - "custom": { - "xLabel": "Fujin", - "yLabel": "103 104" - }, - "category": "Fujin", - "y": 103104 - }, - { - "custom": { - "xLabel": "Cabimas", - "yLabel": "221 329" - }, - "category": "Cabimas", - "y": 221329 - }, - { - "custom": { - "xLabel": "Mayagüez", - "yLabel": "98 434" - }, - "category": "Mayagüez", - "y": 98434 - }, - { - "custom": { - "xLabel": "Stamford", - "yLabel": "117 083" - }, - "category": "Stamford", - "y": 117083 - }, - { - "custom": { - "xLabel": "Accra", - "yLabel": "1 070 000" - }, - "category": "Accra", - "y": 1070000 - }, - { - "custom": { - "xLabel": "Jamestown", - "yLabel": "1 500" - }, - "category": "Jamestown", - "y": 1500 - }, - { - "custom": { - "xLabel": "Garapan", - "yLabel": "9 200" - }, - "category": "Garapan", - "y": 9200 - }, - { - "custom": { - "xLabel": "Reggio nell´ Emilia", - "yLabel": "143 664" - }, - "category": "Reggio nell´ Emilia", - "y": 143664 - }, - { - "custom": { - "xLabel": "Nawabshah", - "yLabel": "183 100" - }, - "category": "Nawabshah", - "y": 183100 - }, - { - "custom": { - "xLabel": "Lianyungang", - "yLabel": "354 139" - }, - "category": "Lianyungang", - "y": 354139 - }, - { - "custom": { - "xLabel": "Marl", - "yLabel": "93 735" - }, - "category": "Marl", - "y": 93735 - }, - { - "custom": { - "xLabel": "Brasov", - "yLabel": "314 225" - }, - "category": "Brasov", - "y": 314225 - }, - { - "custom": { - "xLabel": "Praia", - "yLabel": "94 800" - }, - "category": "Praia", - "y": 94800 - }, - { - "custom": { - "xLabel": "Lübeck", - "yLabel": "213 326" - }, - "category": "Lübeck", - "y": 213326 - }, - { - "custom": { - "xLabel": "Rio Claro", - "yLabel": "163 551" - }, - "category": "Rio Claro", - "y": 163551 - }, - { - "custom": { - "xLabel": "Bayawan (Tulong)", - "yLabel": "101 391" - }, - "category": "Bayawan (Tulong)", - "y": 101391 - }, - { - "custom": { - "xLabel": "Abakan", - "yLabel": "169 200" - }, - "category": "Abakan", - "y": 169200 - }, - { - "custom": { - "xLabel": "Mudanjiang", - "yLabel": "570 000" - }, - "category": "Mudanjiang", - "y": 570000 - }, - { - "custom": { - "xLabel": "Göttingen", - "yLabel": "124 775" - }, - "category": "Göttingen", - "y": 124775 - }, - { - "custom": { - "xLabel": "al-Khubar", - "yLabel": "141 700" - }, - "category": "al-Khubar", - "y": 141700 - }, - { - "custom": { - "xLabel": "Klaipeda", - "yLabel": "202 451" - }, - "category": "Klaipeda", - "y": 202451 - }, - { - "custom": { - "xLabel": "Bislig", - "yLabel": "97 860" - }, - "category": "Bislig", - "y": 97860 - }, - { - "custom": { - "xLabel": "Porto Alegre", - "yLabel": "1 314 032" - }, - "category": "Porto Alegre", - "y": 1314032 - }, - { - "custom": { - "xLabel": "Huejutla de Reyes", - "yLabel": "108 017" - }, - "category": "Huejutla de Reyes", - "y": 108017 - }, - { - "custom": { - "xLabel": "Batangas", - "yLabel": "247 588" - }, - "category": "Batangas", - "y": 247588 - }, - { - "custom": { - "xLabel": "Kaunas", - "yLabel": "412 639" - }, - "category": "Kaunas", - "y": 412639 - }, - { - "custom": { - "xLabel": "Iloilo", - "yLabel": "365 820" - }, - "category": "Iloilo", - "y": 365820 - }, - { - "custom": { - "xLabel": "Panevezys", - "yLabel": "133 695" - }, - "category": "Panevezys", - "y": 133695 - }, - { - "custom": { - "xLabel": "Mbabane", - "yLabel": "61 000" - }, - "category": "Mbabane", - "y": 61000 - }, - { - "custom": { - "xLabel": "Srinagar", - "yLabel": "892 506" - }, - "category": "Srinagar", - "y": 892506 - }, - { - "custom": { - "xLabel": "Staryi Oskol", - "yLabel": "213 800" - }, - "category": "Staryi Oskol", - "y": 213800 - }, - { - "custom": { - "xLabel": "Mata-Utu", - "yLabel": "1 137" - }, - "category": "Mata-Utu", - "y": 1137 - }, - { - "custom": { - "xLabel": "Neuss", - "yLabel": "149 702" - }, - "category": "Neuss", - "y": 149702 - }, - { - "custom": { - "xLabel": "Alvorada", - "yLabel": "175 574" - }, - "category": "Alvorada", - "y": 175574 - }, - { - "custom": { - "xLabel": "Slough", - "yLabel": "112 000" - }, - "category": "Slough", - "y": 112000 - }, - { - "custom": { - "xLabel": "George", - "yLabel": "93 818" - }, - "category": "George", - "y": 93818 - }, - { - "custom": { - "xLabel": "Nyiregyháza", - "yLabel": "112 419" - }, - "category": "Nyiregyháza", - "y": 112419 - }, - { - "custom": { - "xLabel": "Kuching", - "yLabel": "148 059" - }, - "category": "Kuching", - "y": 148059 - }, - { - "custom": { - "xLabel": "Querétaro", - "yLabel": "639 839" - }, - "category": "Querétaro", - "y": 639839 - }, - { - "custom": { - "xLabel": "San Salvador", - "yLabel": "415 346" - }, - "category": "San Salvador", - "y": 415346 - }, - { - "custom": { - "xLabel": "Resende", - "yLabel": "100 627" - }, - "category": "Resende", - "y": 100627 - }, - { - "custom": { - "xLabel": "Agege", - "yLabel": "105 000" - }, - "category": "Agege", - "y": 105000 - }, - { - "custom": { - "xLabel": "Ezhou", - "yLabel": "190 123" - }, - "category": "Ezhou", - "y": 190123 - }, - { - "custom": { - "xLabel": "Uji", - "yLabel": "188 735" - }, - "category": "Uji", - "y": 188735 - }, - { - "custom": { - "xLabel": "Kunming", - "yLabel": "1 829 500" - }, - "category": "Kunming", - "y": 1829500 - }, - { - "custom": { - "xLabel": "Ingolstadt", - "yLabel": "114 826" - }, - "category": "Ingolstadt", - "y": 114826 - }, - { - "custom": { - "xLabel": "Guagua", - "yLabel": "96 858" - }, - "category": "Guagua", - "y": 96858 - }, - { - "custom": { - "xLabel": "Sanda", - "yLabel": "105 643" - }, - "category": "Sanda", - "y": 105643 - }, - { - "custom": { - "xLabel": "Zamboanga", - "yLabel": "601 794" - }, - "category": "Zamboanga", - "y": 601794 - }, - { - "custom": { - "xLabel": "Monza", - "yLabel": "119 516" - }, - "category": "Monza", - "y": 119516 - }, - { - "custom": { - "xLabel": "Angarsk", - "yLabel": "264 700" - }, - "category": "Angarsk", - "y": 264700 - }, - { - "custom": { - "xLabel": "Buga", - "yLabel": "110 699" - }, - "category": "Buga", - "y": 110699 - }, - { - "custom": { - "xLabel": "Santana do Livramento", - "yLabel": "91 779" - }, - "category": "Santana do Livramento", - "y": 91779 - }, - { - "custom": { - "xLabel": "Ibirité", - "yLabel": "125 982" - }, - "category": "Ibirité", - "y": 125982 - }, - { - "custom": { - "xLabel": "Pagadian", - "yLabel": "142 515" - }, - "category": "Pagadian", - "y": 142515 - }, - { - "custom": { - "xLabel": "Omaha", - "yLabel": "390 007" - }, - "category": "Omaha", - "y": 390007 - }, - { - "custom": { - "xLabel": "Dabgram", - "yLabel": "147 217" - }, - "category": "Dabgram", - "y": 147217 - }, - { - "custom": { - "xLabel": "Yichang", - "yLabel": "371 601" - }, - "category": "Yichang", - "y": 371601 - }, - { - "custom": { - "xLabel": "Matsuyama", - "yLabel": "466 133" - }, - "category": "Matsuyama", - "y": 466133 - }, - { - "custom": { - "xLabel": "San Luis", - "yLabel": "110 136" - }, - "category": "San Luis", - "y": 110136 - }, - { - "custom": { - "xLabel": "Wellington", - "yLabel": "166 700" - }, - "category": "Wellington", - "y": 166700 - }, - { - "custom": { - "xLabel": "Palermo", - "yLabel": "683 794" - }, - "category": "Palermo", - "y": 683794 - }, - { - "custom": { - "xLabel": "Arecibo", - "yLabel": "100 131" - }, - "category": "Arecibo", - "y": 100131 - }, - { - "custom": { - "xLabel": "Jiaohe", - "yLabel": "176 367" - }, - "category": "Jiaohe", - "y": 176367 - }, - { - "custom": { - "xLabel": "Midland", - "yLabel": "98 293" - }, - "category": "Midland", - "y": 98293 - }, - { - "custom": { - "xLabel": "Astrahan", - "yLabel": "486 100" - }, - "category": "Astrahan", - "y": 486100 - }, - { - "custom": { - "xLabel": "Mandya", - "yLabel": "120 265" - }, - "category": "Mandya", - "y": 120265 - }, - { - "custom": { - "xLabel": "Macapá", - "yLabel": "256 033" - }, - "category": "Macapá", - "y": 256033 - }, - { - "custom": { - "xLabel": "Hermosillo", - "yLabel": "608 697" - }, - "category": "Hermosillo", - "y": 608697 - }, - { - "custom": { - "xLabel": "Tangail", - "yLabel": "106 004" - }, - "category": "Tangail", - "y": 106004 - }, - { - "custom": { - "xLabel": "Gongziling", - "yLabel": "226 569" - }, - "category": "Gongziling", - "y": 226569 - }, - { - "custom": { - "xLabel": "Matsusaka", - "yLabel": "123 582" - }, - "category": "Matsusaka", - "y": 123582 - }, - { - "custom": { - "xLabel": "Thane (Thana)", - "yLabel": "803 389" - }, - "category": "Thane (Thana)", - "y": 803389 - }, - { - "custom": { - "xLabel": "Stockholm", - "yLabel": "750 348" - }, - "category": "Stockholm", - "y": 750348 - }, - { - "custom": { - "xLabel": "Palghat (Palakkad)", - "yLabel": "123 289" - }, - "category": "Palghat (Palakkad)", - "y": 123289 - }, - { - "custom": { - "xLabel": "Dos Hermanas", - "yLabel": "94 591" - }, - "category": "Dos Hermanas", - "y": 94591 - }, - { - "custom": { - "xLabel": "Tripoli", - "yLabel": "1 682 000" - }, - "category": "Tripoli", - "y": 1682000 - }, - { - "custom": { - "xLabel": "Yichun", - "yLabel": "800 000" - }, - "category": "Yichun", - "y": 800000 - }, - { - "custom": { - "xLabel": "Koudougou", - "yLabel": "105 000" - }, - "category": "Koudougou", - "y": 105000 - }, - { - "custom": { - "xLabel": "Curitiba", - "yLabel": "1 584 232" - }, - "category": "Curitiba", - "y": 1584232 - }, - { - "custom": { - "xLabel": "Chittoor", - "yLabel": "133 462" - }, - "category": "Chittoor", - "y": 133462 - }, - { - "custom": { - "xLabel": "Chimalhuacán", - "yLabel": "490 245" - }, - "category": "Chimalhuacán", - "y": 490245 - }, - { - "custom": { - "xLabel": "Yokosuka", - "yLabel": "430 200" - }, - "category": "Yokosuka", - "y": 430200 - }, - { - "custom": { - "xLabel": "Dourados", - "yLabel": "164 716" - }, - "category": "Dourados", - "y": 164716 - }, - { - "custom": { - "xLabel": "São José dos Pinhais", - "yLabel": "196 884" - }, - "category": "São José dos Pinhais", - "y": 196884 - }, - { - "custom": { - "xLabel": "Cockburn Town", - "yLabel": "4 800" - }, - "category": "Cockburn Town", - "y": 4800 - }, - { - "custom": { - "xLabel": "Izmir", - "yLabel": "2 130 359" - }, - "category": "Izmir", - "y": 2130359 - }, - { - "custom": { - "xLabel": "Bhuj", - "yLabel": "102 176" - }, - "category": "Bhuj", - "y": 102176 - }, - { - "custom": { - "xLabel": "Itu", - "yLabel": "132 736" - }, - "category": "Itu", - "y": 132736 - }, - { - "custom": { - "xLabel": "Qaraghandy", - "yLabel": "436 900" - }, - "category": "Qaraghandy", - "y": 436900 - }, - { - "custom": { - "xLabel": "Aurora", - "yLabel": "276 393" - }, - "category": "Aurora", - "y": 276393 - }, - { - "custom": { - "xLabel": "Jabalpur", - "yLabel": "741 927" - }, - "category": "Jabalpur", - "y": 741927 - }, - { - "custom": { - "xLabel": "Syktyvkar", - "yLabel": "229 700" - }, - "category": "Syktyvkar", - "y": 229700 - }, - { - "custom": { - "xLabel": "Mandasor", - "yLabel": "95 758" - }, - "category": "Mandasor", - "y": 95758 - }, - { - "custom": { - "xLabel": "Eindhoven", - "yLabel": "201 843" - }, - "category": "Eindhoven", - "y": 201843 - }, - { - "custom": { - "xLabel": "South Hill", - "yLabel": "961" - }, - "category": "South Hill", - "y": 961 - }, - { - "custom": { - "xLabel": "Burayda", - "yLabel": "248 600" - }, - "category": "Burayda", - "y": 248600 - }, - { - "custom": { - "xLabel": "Zhoukou", - "yLabel": "146 288" - }, - "category": "Zhoukou", - "y": 146288 - }, - { - "custom": { - "xLabel": "Burgos", - "yLabel": "162 802" - }, - "category": "Burgos", - "y": 162802 - }, - { - "custom": { - "xLabel": "Rohtak", - "yLabel": "233 400" - }, - "category": "Rohtak", - "y": 233400 - }, - { - "custom": { - "xLabel": "Surat", - "yLabel": "1 498 817" - }, - "category": "Surat", - "y": 1498817 - }, - { - "custom": { - "xLabel": "Solingen", - "yLabel": "165 583" - }, - "category": "Solingen", - "y": 165583 - }, - { - "custom": { - "xLabel": "Gaza", - "yLabel": "353 632" - }, - "category": "Gaza", - "y": 353632 - }, - { - "custom": { - "xLabel": "Soligorsk", - "yLabel": "101 000" - }, - "category": "Soligorsk", - "y": 101000 - }, - { - "custom": { - "xLabel": "Elizabeth", - "yLabel": "120 568" - }, - "category": "Elizabeth", - "y": 120568 - }, - { - "custom": { - "xLabel": "Laiwu", - "yLabel": "246 833" - }, - "category": "Laiwu", - "y": 246833 - }, - { - "custom": { - "xLabel": "Montgomery", - "yLabel": "201 568" - }, - "category": "Montgomery", - "y": 201568 - }, - { - "custom": { - "xLabel": "Cincinnati", - "yLabel": "331 285" - }, - "category": "Cincinnati", - "y": 331285 - }, - { - "custom": { - "xLabel": "Shuangyashan", - "yLabel": "386 081" - }, - "category": "Shuangyashan", - "y": 386081 - }, - { - "custom": { - "xLabel": "Nagareyama", - "yLabel": "147 738" - }, - "category": "Nagareyama", - "y": 147738 - }, - { - "custom": { - "xLabel": "Liaoyang", - "yLabel": "492 559" - }, - "category": "Liaoyang", - "y": 492559 - }, - { - "custom": { - "xLabel": "Taboão da Serra", - "yLabel": "197 550" - }, - "category": "Taboão da Serra", - "y": 197550 - }, - { - "custom": { - "xLabel": "Santa Clara", - "yLabel": "207 350" - }, - "category": "Santa Clara", - "y": 207350 - }, - { - "custom": { - "xLabel": "Miyakonojo", - "yLabel": "133 183" - }, - "category": "Miyakonojo", - "y": 133183 - }, - { - "custom": { - "xLabel": "Uttarpara-Kotrung", - "yLabel": "100 867" - }, - "category": "Uttarpara-Kotrung", - "y": 100867 - }, - { - "custom": { - "xLabel": "Puerto Princesa", - "yLabel": "161 912" - }, - "category": "Puerto Princesa", - "y": 161912 - }, - { - "custom": { - "xLabel": "Ottawa", - "yLabel": "335 277" - }, - "category": "Ottawa", - "y": 335277 - }, - { - "custom": { - "xLabel": "Pokhara", - "yLabel": "146 318" - }, - "category": "Pokhara", - "y": 146318 - }, - { - "custom": { - "xLabel": "Madiun", - "yLabel": "171 532" - }, - "category": "Madiun", - "y": 171532 - }, - { - "custom": { - "xLabel": "Coquimbo", - "yLabel": "143 353" - }, - "category": "Coquimbo", - "y": 143353 - }, - { - "custom": { - "xLabel": "Silang", - "yLabel": "156 137" - }, - "category": "Silang", - "y": 156137 - }, - { - "custom": { - "xLabel": "Innsbruck", - "yLabel": "111 752" - }, - "category": "Innsbruck", - "y": 111752 - }, - { - "custom": { - "xLabel": "Shah Alam", - "yLabel": "102 019" - }, - "category": "Shah Alam", - "y": 102019 - }, - { - "custom": { - "xLabel": "Oleksandrija", - "yLabel": "99 000" - }, - "category": "Oleksandrija", - "y": 99000 - }, - { - "custom": { - "xLabel": "Nouâdhibou", - "yLabel": "97 600" - }, - "category": "Nouâdhibou", - "y": 97600 - }, - { - "custom": { - "xLabel": "Kamoke", - "yLabel": "151 000" - }, - "category": "Kamoke", - "y": 151000 - }, - { - "custom": { - "xLabel": "Pescara", - "yLabel": "115 698" - }, - "category": "Pescara", - "y": 115698 - }, - { - "custom": { - "xLabel": "Mossoró", - "yLabel": "214 901" - }, - "category": "Mossoró", - "y": 214901 - }, - { - "custom": { - "xLabel": "Knoxville", - "yLabel": "173 890" - }, - "category": "Knoxville", - "y": 173890 - }, - { - "custom": { - "xLabel": "Braga", - "yLabel": "90 535" - }, - "category": "Braga", - "y": 90535 - }, - { - "custom": { - "xLabel": "Reykjavík", - "yLabel": "109 184" - }, - "category": "Reykjavík", - "y": 109184 - }, - { - "custom": { - "xLabel": "Córdoba", - "yLabel": "311 708" - }, - "category": "Córdoba", - "y": 311708 - }, - { - "custom": { - "xLabel": "Nossa Senhora do Socorro", - "yLabel": "131 351" - }, - "category": "Nossa Senhora do Socorro", - "y": 131351 - }, - { - "custom": { - "xLabel": "Godhra", - "yLabel": "96 813" - }, - "category": "Godhra", - "y": 96813 - }, - { - "custom": { - "xLabel": "Springfield", - "yLabel": "111 454" - }, - "category": "Springfield", - "y": 111454 - }, - { - "custom": { - "xLabel": "Asahikawa", - "yLabel": "364 813" - }, - "category": "Asahikawa", - "y": 364813 - }, - { - "custom": { - "xLabel": "Wollongong", - "yLabel": "219 761" - }, - "category": "Wollongong", - "y": 219761 - }, - { - "custom": { - "xLabel": "Murmansk", - "yLabel": "376 300" - }, - "category": "Murmansk", - "y": 376300 - }, - { - "custom": { - "xLabel": "Chandrapur", - "yLabel": "226 105" - }, - "category": "Chandrapur", - "y": 226105 - }, - { - "custom": { - "xLabel": "Kaesong", - "yLabel": "171 500" - }, - "category": "Kaesong", - "y": 171500 - }, - { - "custom": { - "xLabel": "Stara Zagora", - "yLabel": "147 939" - }, - "category": "Stara Zagora", - "y": 147939 - }, - { - "custom": { - "xLabel": "London", - "yLabel": "339 917" - }, - "category": "London", - "y": 339917 - }, - { - "custom": { - "xLabel": "Naju", - "yLabel": "107 831" - }, - "category": "Naju", - "y": 107831 - }, - { - "custom": { - "xLabel": "Westonaria", - "yLabel": "159 632" - }, - "category": "Westonaria", - "y": 159632 - }, - { - "custom": { - "xLabel": "St Petersburg", - "yLabel": "4 694 000" - }, - "category": "St Petersburg", - "y": 4694000 - }, - { - "custom": { - "xLabel": "Puyang", - "yLabel": "175 988" - }, - "category": "Puyang", - "y": 175988 - }, - { - "custom": { - "xLabel": "Rach Gia", - "yLabel": "141 132" - }, - "category": "Rach Gia", - "y": 141132 - }, - { - "custom": { - "xLabel": "Ogaki", - "yLabel": "151 758" - }, - "category": "Ogaki", - "y": 151758 - }, - { - "custom": { - "xLabel": "Ciudad de Panamá", - "yLabel": "471 373" - }, - "category": "Ciudad de Panamá", - "y": 471373 - }, - { - "custom": { - "xLabel": "Matsue", - "yLabel": "149 821" - }, - "category": "Matsue", - "y": 149821 - }, - { - "custom": { - "xLabel": "Natal", - "yLabel": "688 955" - }, - "category": "Natal", - "y": 688955 - }, - { - "custom": { - "xLabel": "Patan", - "yLabel": "96 109" - }, - "category": "Patan", - "y": 96109 - }, - { - "custom": { - "xLabel": "Shivapuri", - "yLabel": "108 277" - }, - "category": "Shivapuri", - "y": 108277 - }, - { - "custom": { - "xLabel": "Central Coast", - "yLabel": "227 657" - }, - "category": "Central Coast", - "y": 227657 - }, - { - "custom": { - "xLabel": "Sudbury", - "yLabel": "92 686" - }, - "category": "Sudbury", - "y": 92686 - }, - { - "custom": { - "xLabel": "Vitebsk", - "yLabel": "340 000" - }, - "category": "Vitebsk", - "y": 340000 - }, - { - "custom": { - "xLabel": "Banjarmasin", - "yLabel": "482 931" - }, - "category": "Banjarmasin", - "y": 482931 - }, - { - "custom": { - "xLabel": "Chattanooga", - "yLabel": "155 554" - }, - "category": "Chattanooga", - "y": 155554 - }, - { - "custom": { - "xLabel": "Santa Luzia", - "yLabel": "164 704" - }, - "category": "Santa Luzia", - "y": 164704 - }, - { - "custom": { - "xLabel": "Tampa", - "yLabel": "303 447" - }, - "category": "Tampa", - "y": 303447 - }, - { - "custom": { - "xLabel": "Nantong", - "yLabel": "343 341" - }, - "category": "Nantong", - "y": 343341 - }, - { - "custom": { - "xLabel": "El Monte", - "yLabel": "115 965" - }, - "category": "El Monte", - "y": 115965 - }, - { - "custom": { - "xLabel": "Matsumoto", - "yLabel": "206 801" - }, - "category": "Matsumoto", - "y": 206801 - }, - { - "custom": { - "xLabel": "Cosoleacaque", - "yLabel": "97 199" - }, - "category": "Cosoleacaque", - "y": 97199 - }, - { - "custom": { - "xLabel": "Margilon", - "yLabel": "140 800" - }, - "category": "Margilon", - "y": 140800 - }, - { - "custom": { - "xLabel": "Chittagong", - "yLabel": "1 392 860" - }, - "category": "Chittagong", - "y": 1392860 - }, - { - "custom": { - "xLabel": "Iquitos", - "yLabel": "367 000" - }, - "category": "Iquitos", - "y": 367000 - }, - { - "custom": { - "xLabel": "Wonsan", - "yLabel": "300 148" - }, - "category": "Wonsan", - "y": 300148 - }, - { - "custom": { - "xLabel": "Detroit", - "yLabel": "951 270" - }, - "category": "Detroit", - "y": 951270 - }, - { - "custom": { - "xLabel": "Getafe", - "yLabel": "145 371" - }, - "category": "Getafe", - "y": 145371 - }, - { - "custom": { - "xLabel": "Mukatševe", - "yLabel": "89 000" - }, - "category": "Mukatševe", - "y": 89000 - }, - { - "custom": { - "xLabel": "Karlsruhe", - "yLabel": "277 204" - }, - "category": "Karlsruhe", - "y": 277204 - }, - { - "custom": { - "xLabel": "Morvi", - "yLabel": "90 357" - }, - "category": "Morvi", - "y": 90357 - }, - { - "custom": { - "xLabel": "Nara", - "yLabel": "362 812" - }, - "category": "Nara", - "y": 362812 - }, - { - "custom": { - "xLabel": "Gujranwala", - "yLabel": "1 124 749" - }, - "category": "Gujranwala", - "y": 1124749 - }, - { - "custom": { - "xLabel": "Zhoushan", - "yLabel": "156 317" - }, - "category": "Zhoushan", - "y": 156317 - }, - { - "custom": { - "xLabel": "Yuanjiang", - "yLabel": "107 004" - }, - "category": "Yuanjiang", - "y": 107004 - }, - { - "custom": { - "xLabel": "Baranovitši", - "yLabel": "167 000" - }, - "category": "Baranovitši", - "y": 167000 - }, - { - "custom": { - "xLabel": "Abiko", - "yLabel": "126 670" - }, - "category": "Abiko", - "y": 126670 - }, - { - "custom": { - "xLabel": "Oldbury/Smethwick (Warley)", - "yLabel": "145 542" - }, - "category": "Oldbury/Smethwick (Warley)", - "y": 145542 - }, - { - "custom": { - "xLabel": "Rustavi", - "yLabel": "155 400" - }, - "category": "Rustavi", - "y": 155400 - }, - { - "custom": { - "xLabel": "Santiago del Estero", - "yLabel": "189 947" - }, - "category": "Santiago del Estero", - "y": 189947 - }, - { - "custom": { - "xLabel": "Kansas City", - "yLabel": "441 545" - }, - "category": "Kansas City", - "y": 441545 - }, - { - "custom": { - "xLabel": "Valencia", - "yLabel": "147 924" - }, - "category": "Valencia", - "y": 147924 - }, - { - "custom": { - "xLabel": "Tangerang", - "yLabel": "1 198 300" - }, - "category": "Tangerang", - "y": 1198300 - }, - { - "custom": { - "xLabel": "Ambon", - "yLabel": "249 312" - }, - "category": "Ambon", - "y": 249312 - }, - { - "custom": { - "xLabel": "Chicago", - "yLabel": "2 896 016" - }, - "category": "Chicago", - "y": 2896016 - }, - { - "custom": { - "xLabel": "Jacobabad", - "yLabel": "137 700" - }, - "category": "Jacobabad", - "y": 137700 - }, - { - "custom": { - "xLabel": "Murom", - "yLabel": "142 400" - }, - "category": "Murom", - "y": 142400 - }, - { - "custom": { - "xLabel": "Tsu", - "yLabel": "164 543" - }, - "category": "Tsu", - "y": 164543 - }, - { - "custom": { - "xLabel": "Raigarh", - "yLabel": "89 166" - }, - "category": "Raigarh", - "y": 89166 - }, - { - "custom": { - "xLabel": "Saint George´s", - "yLabel": "4 621" - }, - "category": "Saint George´s", - "y": 4621 - }, - { - "custom": { - "xLabel": "Bandar Seri Begawan", - "yLabel": "21 484" - }, - "category": "Bandar Seri Begawan", - "y": 21484 - }, - { - "custom": { - "xLabel": "Araguari", - "yLabel": "98 399" - }, - "category": "Araguari", - "y": 98399 - }, - { - "custom": { - "xLabel": "Kampala", - "yLabel": "890 800" - }, - "category": "Kampala", - "y": 890800 - }, - { - "custom": { - "xLabel": "Pucallpa", - "yLabel": "220 866" - }, - "category": "Pucallpa", - "y": 220866 - }, - { - "custom": { - "xLabel": "Moroni", - "yLabel": "36 000" - }, - "category": "Moroni", - "y": 36000 - }, - { - "custom": { - "xLabel": "Catanzaro", - "yLabel": "96 700" - }, - "category": "Catanzaro", - "y": 96700 - }, - { - "custom": { - "xLabel": "Elâzig", - "yLabel": "228 815" - }, - "category": "Elâzig", - "y": 228815 - }, - { - "custom": { - "xLabel": "Jelets", - "yLabel": "119 400" - }, - "category": "Jelets", - "y": 119400 - }, - { - "custom": { - "xLabel": "Basse-Terre", - "yLabel": "12 433" - }, - "category": "Basse-Terre", - "y": 12433 - }, - { - "custom": { - "xLabel": "San José del Monte", - "yLabel": "315 807" - }, - "category": "San José del Monte", - "y": 315807 - }, - { - "custom": { - "xLabel": "Cusco", - "yLabel": "291 000" - }, - "category": "Cusco", - "y": 291000 - }, - { - "custom": { - "xLabel": "Ormoc", - "yLabel": "154 297" - }, - "category": "Ormoc", - "y": 154297 - }, - { - "custom": { - "xLabel": "Cagliari", - "yLabel": "165 926" - }, - "category": "Cagliari", - "y": 165926 - }, - { - "custom": { - "xLabel": "Moundou", - "yLabel": "99 500" - }, - "category": "Moundou", - "y": 99500 - }, - { - "custom": { - "xLabel": "Zhuzhou", - "yLabel": "409 924" - }, - "category": "Zhuzhou", - "y": 409924 - }, - { - "custom": { - "xLabel": "Dezful", - "yLabel": "202 639" - }, - "category": "Dezful", - "y": 202639 - }, - { - "custom": { - "xLabel": "Jalna", - "yLabel": "174 985" - }, - "category": "Jalna", - "y": 174985 - }, - { - "custom": { - "xLabel": "Qandahar", - "yLabel": "237 500" - }, - "category": "Qandahar", - "y": 237500 - }, - { - "custom": { - "xLabel": "Erzurum", - "yLabel": "246 535" - }, - "category": "Erzurum", - "y": 246535 - }, - { - "custom": { - "xLabel": "Omsk", - "yLabel": "1 148 900" - }, - "category": "Omsk", - "y": 1148900 - }, - { - "custom": { - "xLabel": "Fairfield", - "yLabel": "92 256" - }, - "category": "Fairfield", - "y": 92256 - }, - { - "custom": { - "xLabel": "Cuautitlán Izcalli", - "yLabel": "452 976" - }, - "category": "Cuautitlán Izcalli", - "y": 452976 - }, - { - "custom": { - "xLabel": "Hamm", - "yLabel": "181 804" - }, - "category": "Hamm", - "y": 181804 - }, - { - "custom": { - "xLabel": "Dali", - "yLabel": "136 554" - }, - "category": "Dali", - "y": 136554 - }, - { - "custom": { - "xLabel": "Rivne", - "yLabel": "245 000" - }, - "category": "Rivne", - "y": 245000 - }, - { - "custom": { - "xLabel": "Huizhou", - "yLabel": "161 023" - }, - "category": "Huizhou", - "y": 161023 - }, - { - "custom": { - "xLabel": "Tijuana", - "yLabel": "1 212 232" - }, - "category": "Tijuana", - "y": 1212232 - }, - { - "custom": { - "xLabel": "Almoloya de Juárez", - "yLabel": "110 550" - }, - "category": "Almoloya de Juárez", - "y": 110550 - }, - { - "custom": { - "xLabel": "Firenze", - "yLabel": "376 662" - }, - "category": "Firenze", - "y": 376662 - }, - { - "custom": { - "xLabel": "Yongchon", - "yLabel": "113 511" - }, - "category": "Yongchon", - "y": 113511 - }, - { - "custom": { - "xLabel": "Linqing", - "yLabel": "123 958" - }, - "category": "Linqing", - "y": 123958 - }, - { - "custom": { - "xLabel": "Port-au-Prince", - "yLabel": "884 472" - }, - "category": "Port-au-Prince", - "y": 884472 - }, - { - "custom": { - "xLabel": "Christchurch", - "yLabel": "324 200" - }, - "category": "Christchurch", - "y": 324200 - }, - { - "custom": { - "xLabel": "Namyangju", - "yLabel": "229 060" - }, - "category": "Namyangju", - "y": 229060 - }, - { - "custom": { - "xLabel": "Harkova [Harkiv]", - "yLabel": "1 500 000" - }, - "category": "Harkova [Harkiv]", - "y": 1500000 - }, - { - "custom": { - "xLabel": "El Tigre", - "yLabel": "116 256" - }, - "category": "El Tigre", - "y": 116256 - }, - { - "custom": { - "xLabel": "Cambridge", - "yLabel": "101 355" - }, - "category": "Cambridge", - "y": 101355 - }, - { - "custom": { - "xLabel": "Muzaffargarh", - "yLabel": "121 600" - }, - "category": "Muzaffargarh", - "y": 121600 - }, - { - "custom": { - "xLabel": "Chongjin", - "yLabel": "582 480" - }, - "category": "Chongjin", - "y": 582480 - }, - { - "custom": { - "xLabel": "Terni", - "yLabel": "107 770" - }, - "category": "Terni", - "y": 107770 - }, - { - "custom": { - "xLabel": "Xingtai", - "yLabel": "302 789" - }, - "category": "Xingtai", - "y": 302789 - }, - { - "custom": { - "xLabel": "Birmingham", - "yLabel": "242 820" - }, - "category": "Birmingham", - "y": 242820 - }, - { - "custom": { - "xLabel": "Apucarana", - "yLabel": "105 114" - }, - "category": "Apucarana", - "y": 105114 - }, - { - "custom": { - "xLabel": "Blantyre", - "yLabel": "478 155" - }, - "category": "Blantyre", - "y": 478155 - }, - { - "custom": { - "xLabel": "Taonan", - "yLabel": "150 168" - }, - "category": "Taonan", - "y": 150168 - }, - { - "custom": { - "xLabel": "Xiaoshan", - "yLabel": "162 930" - }, - "category": "Xiaoshan", - "y": 162930 - }, - { - "custom": { - "xLabel": "Cleveland", - "yLabel": "478 403" - }, - "category": "Cleveland", - "y": 478403 - }, - { - "custom": { - "xLabel": "Damanhur", - "yLabel": "212 203" - }, - "category": "Damanhur", - "y": 212203 - }, - { - "custom": { - "xLabel": "Piacenza", - "yLabel": "98 384" - }, - "category": "Piacenza", - "y": 98384 - }, - { - "custom": { - "xLabel": "Waru", - "yLabel": "124 300" - }, - "category": "Waru", - "y": 124300 - }, - { - "custom": { - "xLabel": "Asansol", - "yLabel": "262 188" - }, - "category": "Asansol", - "y": 262188 - }, - { - "custom": { - "xLabel": "Masaya", - "yLabel": "88 971" - }, - "category": "Masaya", - "y": 88971 - }, - { - "custom": { - "xLabel": "Mostaganem", - "yLabel": "115 212" - }, - "category": "Mostaganem", - "y": 115212 - }, - { - "custom": { - "xLabel": "Xinxiang", - "yLabel": "473 762" - }, - "category": "Xinxiang", - "y": 473762 - }, - { - "custom": { - "xLabel": "Túxpam", - "yLabel": "126 475" - }, - "category": "Túxpam", - "y": 126475 - }, - { - "custom": { - "xLabel": "Fuqing", - "yLabel": "99 193" - }, - "category": "Fuqing", - "y": 99193 - }, - { - "custom": { - "xLabel": "São José do Rio Preto", - "yLabel": "351 944" - }, - "category": "São José do Rio Preto", - "y": 351944 - }, - { - "custom": { - "xLabel": "Torrejón de Ardoz", - "yLabel": "92 262" - }, - "category": "Torrejón de Ardoz", - "y": 92262 - }, - { - "custom": { - "xLabel": "Shimonoseki", - "yLabel": "257 263" - }, - "category": "Shimonoseki", - "y": 257263 - }, - { - "custom": { - "xLabel": "Toledo", - "yLabel": "141 174" - }, - "category": "Toledo", - "y": 141174 - }, - { - "custom": { - "xLabel": "Songnam", - "yLabel": "869 094" - }, - "category": "Songnam", - "y": 869094 - }, - { - "custom": { - "xLabel": "Yong´an", - "yLabel": "111 762" - }, - "category": "Yong´an", - "y": 111762 - }, - { - "custom": { - "xLabel": "Baoji", - "yLabel": "337 765" - }, - "category": "Baoji", - "y": 337765 - }, - { - "custom": { - "xLabel": "Bytom", - "yLabel": "205 560" - }, - "category": "Bytom", - "y": 205560 - }, - { - "custom": { - "xLabel": "al-Hilla", - "yLabel": "268 834" - }, - "category": "al-Hilla", - "y": 268834 - }, - { - "custom": { - "xLabel": "Tonk", - "yLabel": "100 079" - }, - "category": "Tonk", - "y": 100079 - }, - { - "custom": { - "xLabel": "Ratlam", - "yLabel": "183 375" - }, - "category": "Ratlam", - "y": 183375 - }, - { - "custom": { - "xLabel": "Pouso Alegre", - "yLabel": "100 028" - }, - "category": "Pouso Alegre", - "y": 100028 - }, - { - "custom": { - "xLabel": "Concordia", - "yLabel": "116 485" - }, - "category": "Concordia", - "y": 116485 - }, - { - "custom": { - "xLabel": "San Francisco del Rincón", - "yLabel": "100 149" - }, - "category": "San Francisco del Rincón", - "y": 100149 - }, - { - "custom": { - "xLabel": "Pak Pattan", - "yLabel": "107 800" - }, - "category": "Pak Pattan", - "y": 107800 - }, - { - "custom": { - "xLabel": "São Luís", - "yLabel": "837 588" - }, - "category": "São Luís", - "y": 837588 - }, - { - "custom": { - "xLabel": "Luton", - "yLabel": "183 000" - }, - "category": "Luton", - "y": 183000 - }, - { - "custom": { - "xLabel": "Ljubljana", - "yLabel": "270 986" - }, - "category": "Ljubljana", - "y": 270986 - }, - { - "custom": { - "xLabel": "La Paz", - "yLabel": "213 045" - }, - "category": "La Paz", - "y": 213045 - }, - { - "custom": { - "xLabel": "Vallejo", - "yLabel": "116 760" - }, - "category": "Vallejo", - "y": 116760 - }, - { - "custom": { - "xLabel": "Sapucaia do Sul", - "yLabel": "120 217" - }, - "category": "Sapucaia do Sul", - "y": 120217 - }, - { - "custom": { - "xLabel": "Vitória da Conquista", - "yLabel": "253 587" - }, - "category": "Vitória da Conquista", - "y": 253587 - }, - { - "custom": { - "xLabel": "Bansberia", - "yLabel": "93 447" - }, - "category": "Bansberia", - "y": 93447 - }, - { - "custom": { - "xLabel": "Augusta-Richmond County", - "yLabel": "199 775" - }, - "category": "Augusta-Richmond County", - "y": 199775 - }, - { - "custom": { - "xLabel": "Cumaná", - "yLabel": "293 105" - }, - "category": "Cumaná", - "y": 293105 - }, - { - "custom": { - "xLabel": "Cesena", - "yLabel": "89 852" - }, - "category": "Cesena", - "y": 89852 - }, - { - "custom": { - "xLabel": "Nantou", - "yLabel": "104 723" - }, - "category": "Nantou", - "y": 104723 - }, - { - "custom": { - "xLabel": "al-Ayn", - "yLabel": "225 970" - }, - "category": "al-Ayn", - "y": 225970 - }, - { - "custom": { - "xLabel": "Lund", - "yLabel": "98 948" - }, - "category": "Lund", - "y": 98948 - }, - { - "custom": { - "xLabel": "Tabriz", - "yLabel": "1 191 043" - }, - "category": "Tabriz", - "y": 1191043 - }, - { - "custom": { - "xLabel": "Bremerhaven", - "yLabel": "122 735" - }, - "category": "Bremerhaven", - "y": 122735 - }, - { - "custom": { - "xLabel": "Patras", - "yLabel": "153 344" - }, - "category": "Patras", - "y": 153344 - }, - { - "custom": { - "xLabel": "Kramatorsk", - "yLabel": "186 000" - }, - "category": "Kramatorsk", - "y": 186000 - }, - { - "custom": { - "xLabel": "Duque de Caxias", - "yLabel": "746 758" - }, - "category": "Duque de Caxias", - "y": 746758 - }, - { - "custom": { - "xLabel": "Ciudad Madero", - "yLabel": "182 012" - }, - "category": "Ciudad Madero", - "y": 182012 - }, - { - "custom": { - "xLabel": "Kaliningrad", - "yLabel": "424 400" - }, - "category": "Kaliningrad", - "y": 424400 - }, - { - "custom": { - "xLabel": "Coatzacoalcos", - "yLabel": "267 037" - }, - "category": "Coatzacoalcos", - "y": 267037 - }, - { - "custom": { - "xLabel": "Graz", - "yLabel": "240 967" - }, - "category": "Graz", - "y": 240967 - }, - { - "custom": { - "xLabel": "Calbayog", - "yLabel": "147 187" - }, - "category": "Calbayog", - "y": 147187 - }, - { - "custom": { - "xLabel": "Westminster", - "yLabel": "100 940" - }, - "category": "Westminster", - "y": 100940 - }, - { - "custom": { - "xLabel": "Jiangmen", - "yLabel": "230 587" - }, - "category": "Jiangmen", - "y": 230587 - }, - { - "custom": { - "xLabel": "Fukuoka", - "yLabel": "1 308 379" - }, - "category": "Fukuoka", - "y": 1308379 - }, - { - "custom": { - "xLabel": "Maastricht", - "yLabel": "122 087" - }, - "category": "Maastricht", - "y": 122087 - }, - { - "custom": { - "xLabel": "Bawshar", - "yLabel": "107 500" - }, - "category": "Bawshar", - "y": 107500 - }, - { - "custom": { - "xLabel": "Caguas", - "yLabel": "140 502" - }, - "category": "Caguas", - "y": 140502 - }, - { - "custom": { - "xLabel": "Brazzaville", - "yLabel": "950 000" - }, - "category": "Brazzaville", - "y": 950000 - }, - { - "custom": { - "xLabel": "Can Tho", - "yLabel": "215 587" - }, - "category": "Can Tho", - "y": 215587 - }, - { - "custom": { - "xLabel": "Sucre", - "yLabel": "178 426" - }, - "category": "Sucre", - "y": 178426 - }, - { - "custom": { - "xLabel": "Iwaki", - "yLabel": "361 737" - }, - "category": "Iwaki", - "y": 361737 - }, - { - "custom": { - "xLabel": "Kénitra", - "yLabel": "292 600" - }, - "category": "Kénitra", - "y": 292600 - }, - { - "custom": { - "xLabel": "Cuddalore", - "yLabel": "153 086" - }, - "category": "Cuddalore", - "y": 153086 - }, - { - "custom": { - "xLabel": "Kendari", - "yLabel": "94 800" - }, - "category": "Kendari", - "y": 94800 - }, - { - "custom": { - "xLabel": "Magnitogorsk", - "yLabel": "427 900" - }, - "category": "Magnitogorsk", - "y": 427900 - }, - { - "custom": { - "xLabel": "Ürgenc", - "yLabel": "138 900" - }, - "category": "Ürgenc", - "y": 138900 - }, - { - "custom": { - "xLabel": "Suez", - "yLabel": "417 610" - }, - "category": "Suez", - "y": 417610 - }, - { - "custom": { - "xLabel": "Lhokseumawe", - "yLabel": "109 600" - }, - "category": "Lhokseumawe", - "y": 109600 - }, - { - "custom": { - "xLabel": "Duran [Eloy Alfaro]", - "yLabel": "152 514" - }, - "category": "Duran [Eloy Alfaro]", - "y": 152514 - }, - { - "custom": { - "xLabel": "Willemstad", - "yLabel": "2 345" - }, - "category": "Willemstad", - "y": 2345 - }, - { - "custom": { - "xLabel": "Sargodha", - "yLabel": "455 360" - }, - "category": "Sargodha", - "y": 455360 - }, - { - "custom": { - "xLabel": "Bijsk", - "yLabel": "225 000" - }, - "category": "Bijsk", - "y": 225000 - }, - { - "custom": { - "xLabel": "Mogiljov", - "yLabel": "356 000" - }, - "category": "Mogiljov", - "y": 356000 - }, - { - "custom": { - "xLabel": "Trondheim", - "yLabel": "150 166" - }, - "category": "Trondheim", - "y": 150166 - }, - { - "custom": { - "xLabel": "Fatehpur", - "yLabel": "117 675" - }, - "category": "Fatehpur", - "y": 117675 - }, - { - "custom": { - "xLabel": "Kislovodsk", - "yLabel": "120 400" - }, - "category": "Kislovodsk", - "y": 120400 - }, - { - "custom": { - "xLabel": "Tirana", - "yLabel": "270 000" - }, - "category": "Tirana", - "y": 270000 - }, - { - "custom": { - "xLabel": "Kyzyl", - "yLabel": "101 100" - }, - "category": "Kyzyl", - "y": 101100 - }, - { - "custom": { - "xLabel": "Marbella", - "yLabel": "101 144" - }, - "category": "Marbella", - "y": 101144 - }, - { - "custom": { - "xLabel": "Loja", - "yLabel": "123 875" - }, - "category": "Loja", - "y": 123875 - }, - { - "custom": { - "xLabel": "Mati", - "yLabel": "105 908" - }, - "category": "Mati", - "y": 105908 - }, - { - "custom": { - "xLabel": "Tanga", - "yLabel": "137 400" - }, - "category": "Tanga", - "y": 137400 - }, - { - "custom": { - "xLabel": "Calama", - "yLabel": "137 265" - }, - "category": "Calama", - "y": 137265 - }, - { - "custom": { - "xLabel": "Bolton", - "yLabel": "139 020" - }, - "category": "Bolton", - "y": 139020 - }, - { - "custom": { - "xLabel": "Roodepoort", - "yLabel": "279 340" - }, - "category": "Roodepoort", - "y": 279340 - }, - { - "custom": { - "xLabel": "Perpignan", - "yLabel": "105 115" - }, - "category": "Perpignan", - "y": 105115 - }, - { - "custom": { - "xLabel": "Farrukhabad-cum-Fatehgarh", - "yLabel": "194 567" - }, - "category": "Farrukhabad-cum-Fatehgarh", - "y": 194567 - }, - { - "custom": { - "xLabel": "Dandong", - "yLabel": "520 000" - }, - "category": "Dandong", - "y": 520000 - }, - { - "custom": { - "xLabel": "Barakaldo", - "yLabel": "98 212" - }, - "category": "Barakaldo", - "y": 98212 - }, - { - "custom": { - "xLabel": "El Jadida", - "yLabel": "119 083" - }, - "category": "El Jadida", - "y": 119083 - }, - { - "custom": { - "xLabel": "Londrina", - "yLabel": "432 257" - }, - "category": "Londrina", - "y": 432257 - }, - { - "custom": { - "xLabel": "Freetown", - "yLabel": "850 000" - }, - "category": "Freetown", - "y": 850000 - }, - { - "custom": { - "xLabel": "San Juan", - "yLabel": "119 152" - }, - "category": "San Juan", - "y": 119152 - }, - { - "custom": { - "xLabel": "York", - "yLabel": "104 425" - }, - "category": "York", - "y": 104425 - }, - { - "custom": { - "xLabel": "Da Nang", - "yLabel": "382 674" - }, - "category": "Da Nang", - "y": 382674 - }, - { - "custom": { - "xLabel": "Nazret", - "yLabel": "127 842" - }, - "category": "Nazret", - "y": 127842 - }, - { - "custom": { - "xLabel": "Prizren", - "yLabel": "92 303" - }, - "category": "Prizren", - "y": 92303 - }, - { - "custom": { - "xLabel": "Szeged", - "yLabel": "158 158" - }, - "category": "Szeged", - "y": 158158 - }, - { - "custom": { - "xLabel": "Umlazi", - "yLabel": "339 233" - }, - "category": "Umlazi", - "y": 339233 - }, - { - "custom": { - "xLabel": "Bahtim", - "yLabel": "275 807" - }, - "category": "Bahtim", - "y": 275807 - }, - { - "custom": { - "xLabel": "Oxnard", - "yLabel": "170 358" - }, - "category": "Oxnard", - "y": 170358 - }, - { - "custom": { - "xLabel": "Soacha", - "yLabel": "272 058" - }, - "category": "Soacha", - "y": 272058 - }, - { - "custom": { - "xLabel": "Ciudad de Guatemala", - "yLabel": "823 301" - }, - "category": "Ciudad de Guatemala", - "y": 823301 - }, - { - "custom": { - "xLabel": "Jaramana", - "yLabel": "138 469" - }, - "category": "Jaramana", - "y": 138469 - }, - { - "custom": { - "xLabel": "Iseyin", - "yLabel": "217 300" - }, - "category": "Iseyin", - "y": 217300 - }, - { - "custom": { - "xLabel": "Pjatigorsk", - "yLabel": "132 500" - }, - "category": "Pjatigorsk", - "y": 132500 - }, - { - "custom": { - "xLabel": "Tierra Blanca", - "yLabel": "89 143" - }, - "category": "Tierra Blanca", - "y": 89143 - }, - { - "custom": { - "xLabel": "Hazaribag", - "yLabel": "97 712" - }, - "category": "Hazaribag", - "y": 97712 - }, - { - "custom": { - "xLabel": "Shangqiu", - "yLabel": "164 880" - }, - "category": "Shangqiu", - "y": 164880 - }, - { - "custom": { - "xLabel": "Ferrara", - "yLabel": "132 127" - }, - "category": "Ferrara", - "y": 132127 - }, - { - "custom": { - "xLabel": "Araure", - "yLabel": "94 269" - }, - "category": "Araure", - "y": 94269 - }, - { - "custom": { - "xLabel": "San Fernando", - "yLabel": "153 036" - }, - "category": "San Fernando", - "y": 153036 - }, - { - "custom": { - "xLabel": "Urayasu", - "yLabel": "127 550" - }, - "category": "Urayasu", - "y": 127550 - }, - { - "custom": { - "xLabel": "Ludwigshafen am Rhein", - "yLabel": "163 771" - }, - "category": "Ludwigshafen am Rhein", - "y": 163771 - }, - { - "custom": { - "xLabel": "Ghaziabad", - "yLabel": "454 156" - }, - "category": "Ghaziabad", - "y": 454156 - }, - { - "custom": { - "xLabel": "Ya´an", - "yLabel": "95 900" - }, - "category": "Ya´an", - "y": 95900 - }, - { - "custom": { - "xLabel": "Matamoros", - "yLabel": "416 428" - }, - "category": "Matamoros", - "y": 416428 - }, - { - "custom": { - "xLabel": "Shillong", - "yLabel": "131 719" - }, - "category": "Shillong", - "y": 131719 - }, - { - "custom": { - "xLabel": "Copiapó", - "yLabel": "120 128" - }, - "category": "Copiapó", - "y": 120128 - }, - { - "custom": { - "xLabel": "Tanshui", - "yLabel": "111 882" - }, - "category": "Tanshui", - "y": 111882 - }, - { - "custom": { - "xLabel": "Atyrau", - "yLabel": "142 500" - }, - "category": "Atyrau", - "y": 142500 - }, - { - "custom": { - "xLabel": "Pondicherry", - "yLabel": "203 065" - }, - "category": "Pondicherry", - "y": 203065 - }, - { - "custom": { - "xLabel": "Yonkers", - "yLabel": "196 086" - }, - "category": "Yonkers", - "y": 196086 - }, - { - "custom": { - "xLabel": "Basirhat", - "yLabel": "101 409" - }, - "category": "Basirhat", - "y": 101409 - }, - { - "custom": { - "xLabel": "Tegal", - "yLabel": "289 744" - }, - "category": "Tegal", - "y": 289744 - }, - { - "custom": { - "xLabel": "Riverside", - "yLabel": "255 166" - }, - "category": "Riverside", - "y": 255166 - }, - { - "custom": { - "xLabel": "Sikar", - "yLabel": "148 272" - }, - "category": "Sikar", - "y": 148272 - }, - { - "custom": { - "xLabel": "Yanji", - "yLabel": "230 892" - }, - "category": "Yanji", - "y": 230892 - }, - { - "custom": { - "xLabel": "Kagoshima", - "yLabel": "549 977" - }, - "category": "Kagoshima", - "y": 549977 - }, - { - "custom": { - "xLabel": "Birigui", - "yLabel": "94 685" - }, - "category": "Birigui", - "y": 94685 - }, - { - "custom": { - "xLabel": "Constantine", - "yLabel": "443 727" - }, - "category": "Constantine", - "y": 443727 - }, - { - "custom": { - "xLabel": "Envigado", - "yLabel": "135 848" - }, - "category": "Envigado", - "y": 135848 - }, - { - "custom": { - "xLabel": "Gatineau", - "yLabel": "100 702" - }, - "category": "Gatineau", - "y": 100702 - }, - { - "custom": { - "xLabel": "Kerman", - "yLabel": "384 991" - }, - "category": "Kerman", - "y": 384991 - }, - { - "custom": { - "xLabel": "Huancayo", - "yLabel": "327 000" - }, - "category": "Huancayo", - "y": 327000 - }, - { - "custom": { - "xLabel": "Rufisque", - "yLabel": "150 000" - }, - "category": "Rufisque", - "y": 150000 - }, - { - "custom": { - "xLabel": "Guaymallén", - "yLabel": "200 595" - }, - "category": "Guaymallén", - "y": 200595 - }, - { - "custom": { - "xLabel": "Salinas", - "yLabel": "151 060" - }, - "category": "Salinas", - "y": 151060 - }, - { - "custom": { - "xLabel": "Baicheng", - "yLabel": "217 987" - }, - "category": "Baicheng", - "y": 217987 - }, - { - "custom": { - "xLabel": "Rockford", - "yLabel": "150 115" - }, - "category": "Rockford", - "y": 150115 - }, - { - "custom": { - "xLabel": "Chifeng", - "yLabel": "350 077" - }, - "category": "Chifeng", - "y": 350077 - }, - { - "custom": { - "xLabel": "Sultan Kudarat", - "yLabel": "94 861" - }, - "category": "Sultan Kudarat", - "y": 94861 - }, - { - "custom": { - "xLabel": "Wuxi", - "yLabel": "830 000" - }, - "category": "Wuxi", - "y": 830000 - }, - { - "custom": { - "xLabel": "La Ceiba", - "yLabel": "89 200" - }, - "category": "La Ceiba", - "y": 89200 - }, - { - "custom": { - "xLabel": "Zinder", - "yLabel": "120 892" - }, - "category": "Zinder", - "y": 120892 - }, - { - "custom": { - "xLabel": "Campinas", - "yLabel": "950 043" - }, - "category": "Campinas", - "y": 950043 - }, - { - "custom": { - "xLabel": "Madison", - "yLabel": "208 054" - }, - "category": "Madison", - "y": 208054 - }, - { - "custom": { - "xLabel": "Serpuhov", - "yLabel": "132 000" - }, - "category": "Serpuhov", - "y": 132000 - }, - { - "custom": { - "xLabel": "Kempton Park", - "yLabel": "442 633" - }, - "category": "Kempton Park", - "y": 442633 - }, - { - "custom": { - "xLabel": "Murcia", - "yLabel": "353 504" - }, - "category": "Murcia", - "y": 353504 - }, - { - "custom": { - "xLabel": "Portland", - "yLabel": "529 121" - }, - "category": "Portland", - "y": 529121 - }, - { - "custom": { - "xLabel": "Galati", - "yLabel": "330 276" - }, - "category": "Galati", - "y": 330276 - }, - { - "custom": { - "xLabel": "Volgograd", - "yLabel": "993 400" - }, - "category": "Volgograd", - "y": 993400 - }, - { - "custom": { - "xLabel": "Tokai", - "yLabel": "99 738" - }, - "category": "Tokai", - "y": 99738 - }, - { - "custom": { - "xLabel": "Târgoviste", - "yLabel": "98 980" - }, - "category": "Târgoviste", - "y": 98980 - }, - { - "custom": { - "xLabel": "Kermanshah", - "yLabel": "692 986" - }, - "category": "Kermanshah", - "y": 692986 - }, - { - "custom": { - "xLabel": "Serra", - "yLabel": "302 666" - }, - "category": "Serra", - "y": 302666 - }, - { - "custom": { - "xLabel": "Agra", - "yLabel": "891 790" - }, - "category": "Agra", - "y": 891790 - }, - { - "custom": { - "xLabel": "Baruta", - "yLabel": "207 290" - }, - "category": "Baruta", - "y": 207290 - }, - { - "custom": { - "xLabel": "Yachiyo", - "yLabel": "161 222" - }, - "category": "Yachiyo", - "y": 161222 - }, - { - "custom": { - "xLabel": "Kalyan", - "yLabel": "1 014 557" - }, - "category": "Kalyan", - "y": 1014557 - }, - { - "custom": { - "xLabel": "Masqat", - "yLabel": "51 969" - }, - "category": "Masqat", - "y": 51969 - }, - { - "custom": { - "xLabel": "Banda", - "yLabel": "97 227" - }, - "category": "Banda", - "y": 97227 - }, - { - "custom": { - "xLabel": "Zelenograd", - "yLabel": "207 100" - }, - "category": "Zelenograd", - "y": 207100 - }, - { - "custom": { - "xLabel": "Gera", - "yLabel": "114 718" - }, - "category": "Gera", - "y": 114718 - }, - { - "custom": { - "xLabel": "Tourcoing", - "yLabel": "93 540" - }, - "category": "Tourcoing", - "y": 93540 - }, - { - "custom": { - "xLabel": "Karawang", - "yLabel": "145 000" - }, - "category": "Karawang", - "y": 145000 - }, - { - "custom": { - "xLabel": "Itapecerica da Serra", - "yLabel": "126 672" - }, - "category": "Itapecerica da Serra", - "y": 126672 - }, - { - "custom": { - "xLabel": "Dashhowuz", - "yLabel": "141 800" - }, - "category": "Dashhowuz", - "y": 141800 - }, - { - "custom": { - "xLabel": "Sotši", - "yLabel": "358 600" - }, - "category": "Sotši", - "y": 358600 - }, - { - "custom": { - "xLabel": "Dolores Hidalgo", - "yLabel": "128 675" - }, - "category": "Dolores Hidalgo", - "y": 128675 - }, - { - "custom": { - "xLabel": "Fresno", - "yLabel": "427 652" - }, - "category": "Fresno", - "y": 427652 - }, - { - "custom": { - "xLabel": "Rustenburg", - "yLabel": "97 008" - }, - "category": "Rustenburg", - "y": 97008 - }, - { - "custom": { - "xLabel": "Pénjamo", - "yLabel": "143 927" - }, - "category": "Pénjamo", - "y": 143927 - }, - { - "custom": { - "xLabel": "Urdaneta", - "yLabel": "111 582" - }, - "category": "Urdaneta", - "y": 111582 - }, - { - "custom": { - "xLabel": "Joinville", - "yLabel": "428 011" - }, - "category": "Joinville", - "y": 428011 - }, - { - "custom": { - "xLabel": "Fuji", - "yLabel": "231 527" - }, - "category": "Fuji", - "y": 231527 - }, - { - "custom": { - "xLabel": "Antsirabé", - "yLabel": "120 239" - }, - "category": "Antsirabé", - "y": 120239 - }, - { - "custom": { - "xLabel": "Suzhou", - "yLabel": "710 000" - }, - "category": "Suzhou", - "y": 710000 - }, - { - "custom": { - "xLabel": "Kunsan", - "yLabel": "266 569" - }, - "category": "Kunsan", - "y": 266569 - }, - { - "custom": { - "xLabel": "Patna", - "yLabel": "917 243" - }, - "category": "Patna", - "y": 917243 - }, - { - "custom": { - "xLabel": "Ugep", - "yLabel": "102 600" - }, - "category": "Ugep", - "y": 102600 - }, - { - "custom": { - "xLabel": "Sharja", - "yLabel": "320 095" - }, - "category": "Sharja", - "y": 320095 - }, - { - "custom": { - "xLabel": "Bloemfontein", - "yLabel": "334 341" - }, - "category": "Bloemfontein", - "y": 334341 - }, - { - "custom": { - "xLabel": "Koje", - "yLabel": "147 562" - }, - "category": "Koje", - "y": 147562 - }, - { - "custom": { - "xLabel": "Johannesburg", - "yLabel": "756 653" - }, - "category": "Johannesburg", - "y": 756653 - }, - { - "custom": { - "xLabel": "Okara", - "yLabel": "200 901" - }, - "category": "Okara", - "y": 200901 - }, - { - "custom": { - "xLabel": "Bratislava", - "yLabel": "448 292" - }, - "category": "Bratislava", - "y": 448292 - }, - { - "custom": { - "xLabel": "Yan´an", - "yLabel": "113 277" - }, - "category": "Yan´an", - "y": 113277 - }, - { - "custom": { - "xLabel": "Baoding", - "yLabel": "483 155" - }, - "category": "Baoding", - "y": 483155 - }, - { - "custom": { - "xLabel": "Ichikawa", - "yLabel": "441 893" - }, - "category": "Ichikawa", - "y": 441893 - }, - { - "custom": { - "xLabel": "Chengde", - "yLabel": "246 799" - }, - "category": "Chengde", - "y": 246799 - }, - { - "custom": { - "xLabel": "Zabrze", - "yLabel": "200 177" - }, - "category": "Zabrze", - "y": 200177 - }, - { - "custom": { - "xLabel": "Yerevan", - "yLabel": "1 248 700" - }, - "category": "Yerevan", - "y": 1248700 - }, - { - "custom": { - "xLabel": "Mbeya", - "yLabel": "130 800" - }, - "category": "Mbeya", - "y": 130800 - }, - { - "custom": { - "xLabel": "Tucheng", - "yLabel": "224 897" - }, - "category": "Tucheng", - "y": 224897 - }, - { - "custom": { - "xLabel": "Jhang", - "yLabel": "292 214" - }, - "category": "Jhang", - "y": 292214 - }, - { - "custom": { - "xLabel": "Yamato", - "yLabel": "208 234" - }, - "category": "Yamato", - "y": 208234 - }, - { - "custom": { - "xLabel": "Bozhou", - "yLabel": "106 346" - }, - "category": "Bozhou", - "y": 106346 - }, - { - "custom": { - "xLabel": "Kano", - "yLabel": "674 100" - }, - "category": "Kano", - "y": 674100 - }, - { - "custom": { - "xLabel": "Ubon Ratchathani", - "yLabel": "116 300" - }, - "category": "Ubon Ratchathani", - "y": 116300 - }, - { - "custom": { - "xLabel": "Jacksonville", - "yLabel": "735 167" - }, - "category": "Jacksonville", - "y": 735167 - }, - { - "custom": { - "xLabel": "Orša", - "yLabel": "124 000" - }, - "category": "Orša", - "y": 124000 - }, - { - "custom": { - "xLabel": "Poza Rica de Hidalgo", - "yLabel": "152 678" - }, - "category": "Poza Rica de Hidalgo", - "y": 152678 - }, - { - "custom": { - "xLabel": "Wuppertal", - "yLabel": "368 993" - }, - "category": "Wuppertal", - "y": 368993 - }, - { - "custom": { - "xLabel": "Nyala", - "yLabel": "227 183" - }, - "category": "Nyala", - "y": 227183 - }, - { - "custom": { - "xLabel": "Mergui (Myeik)", - "yLabel": "122 700" - }, - "category": "Mergui (Myeik)", - "y": 122700 - }, - { - "custom": { - "xLabel": "Andijon", - "yLabel": "318 600" - }, - "category": "Andijon", - "y": 318600 - }, - { - "custom": { - "xLabel": "Vihari", - "yLabel": "92 300" - }, - "category": "Vihari", - "y": 92300 - }, - { - "custom": { - "xLabel": "al-Faiyum", - "yLabel": "260 964" - }, - "category": "al-Faiyum", - "y": 260964 - }, - { - "custom": { - "xLabel": "Stockport", - "yLabel": "132 813" - }, - "category": "Stockport", - "y": 132813 - }, - { - "custom": { - "xLabel": "Katowice", - "yLabel": "345 934" - }, - "category": "Katowice", - "y": 345934 - }, - { - "custom": { - "xLabel": "Kurnool", - "yLabel": "236 800" - }, - "category": "Kurnool", - "y": 236800 - }, - { - "custom": { - "xLabel": "Annaba", - "yLabel": "222 518" - }, - "category": "Annaba", - "y": 222518 - }, - { - "custom": { - "xLabel": "Zwickau", - "yLabel": "104 146" - }, - "category": "Zwickau", - "y": 104146 - }, - { - "custom": { - "xLabel": "Huangyan", - "yLabel": "89 288" - }, - "category": "Huangyan", - "y": 89288 - }, - { - "custom": { - "xLabel": "Tokorozawa", - "yLabel": "325 809" - }, - "category": "Tokorozawa", - "y": 325809 - }, - { - "custom": { - "xLabel": "Qyzylorda", - "yLabel": "157 400" - }, - "category": "Qyzylorda", - "y": 157400 - }, - { - "custom": { - "xLabel": "Kurashiki", - "yLabel": "425 103" - }, - "category": "Kurashiki", - "y": 425103 - }, - { - "custom": { - "xLabel": "Gorgan", - "yLabel": "188 710" - }, - "category": "Gorgan", - "y": 188710 - }, - { - "custom": { - "xLabel": "Morón", - "yLabel": "349 246" - }, - "category": "Morón", - "y": 349246 - }, - { - "custom": { - "xLabel": "Nagoya", - "yLabel": "2 154 376" - }, - "category": "Nagoya", - "y": 2154376 - }, - { - "custom": { - "xLabel": "Tonghae", - "yLabel": "95 472" - }, - "category": "Tonghae", - "y": 95472 - }, - { - "custom": { - "xLabel": "Patiala", - "yLabel": "238 368" - }, - "category": "Patiala", - "y": 238368 - }, - { - "custom": { - "xLabel": "Timkur", - "yLabel": "138 903" - }, - "category": "Timkur", - "y": 138903 - }, - { - "custom": { - "xLabel": "Maceió", - "yLabel": "786 288" - }, - "category": "Maceió", - "y": 786288 - }, - { - "custom": { - "xLabel": "Bydgoszcz", - "yLabel": "386 855" - }, - "category": "Bydgoszcz", - "y": 386855 - }, - { - "custom": { - "xLabel": "Naçala-Porto", - "yLabel": "158 248" - }, - "category": "Naçala-Porto", - "y": 158248 - }, - { - "custom": { - "xLabel": "Ciudad Losada", - "yLabel": "134 501" - }, - "category": "Ciudad Losada", - "y": 134501 - }, - { - "custom": { - "xLabel": "Cabuyao", - "yLabel": "106 630" - }, - "category": "Cabuyao", - "y": 106630 - }, - { - "custom": { - "xLabel": "Trabzon", - "yLabel": "138 234" - }, - "category": "Trabzon", - "y": 138234 - }, - { - "custom": { - "xLabel": "Popayán", - "yLabel": "200 719" - }, - "category": "Popayán", - "y": 200719 - }, - { - "custom": { - "xLabel": "Erode", - "yLabel": "159 232" - }, - "category": "Erode", - "y": 159232 - }, - { - "custom": { - "xLabel": "Huánuco", - "yLabel": "129 688" - }, - "category": "Huánuco", - "y": 129688 - }, - { - "custom": { - "xLabel": "Hmelnytskyi", - "yLabel": "262 000" - }, - "category": "Hmelnytskyi", - "y": 262000 - }, - { - "custom": { - "xLabel": "Chechon", - "yLabel": "137 070" - }, - "category": "Chechon", - "y": 137070 - }, - { - "custom": { - "xLabel": "Bellary", - "yLabel": "245 391" - }, - "category": "Bellary", - "y": 245391 - }, - { - "custom": { - "xLabel": "Da Lat", - "yLabel": "106 409" - }, - "category": "Da Lat", - "y": 106409 - }, - { - "custom": { - "xLabel": "Ramagundam", - "yLabel": "214 384" - }, - "category": "Ramagundam", - "y": 214384 - }, - { - "custom": { - "xLabel": "Liège", - "yLabel": "185 639" - }, - "category": "Liège", - "y": 185639 - }, - { - "custom": { - "xLabel": "Kryvyi Rig", - "yLabel": "703 000" - }, - "category": "Kryvyi Rig", - "y": 703000 - }, - { - "custom": { - "xLabel": "Rabat", - "yLabel": "623 457" - }, - "category": "Rabat", - "y": 623457 - }, - { - "custom": { - "xLabel": "Delmas", - "yLabel": "240 429" - }, - "category": "Delmas", - "y": 240429 - }, - { - "custom": { - "xLabel": "Bhagalpur", - "yLabel": "253 225" - }, - "category": "Bhagalpur", - "y": 253225 - }, - { - "custom": { - "xLabel": "Meihekou", - "yLabel": "209 038" - }, - "category": "Meihekou", - "y": 209038 - }, - { - "custom": { - "xLabel": "Dindigul", - "yLabel": "182 477" - }, - "category": "Dindigul", - "y": 182477 - }, - { - "custom": { - "xLabel": "Kohat", - "yLabel": "125 300" - }, - "category": "Kohat", - "y": 125300 - }, - { - "custom": { - "xLabel": "Sittwe (Akyab)", - "yLabel": "137 600" - }, - "category": "Sittwe (Akyab)", - "y": 137600 - }, - { - "custom": { - "xLabel": "Tanza", - "yLabel": "110 517" - }, - "category": "Tanza", - "y": 110517 - }, - { - "custom": { - "xLabel": "Cartagena", - "yLabel": "177 709" - }, - "category": "Cartagena", - "y": 177709 - }, - { - "custom": { - "xLabel": "Wiesbaden", - "yLabel": "268 716" - }, - "category": "Wiesbaden", - "y": 268716 - }, - { - "custom": { - "xLabel": "Haicheng", - "yLabel": "205 560" - }, - "category": "Haicheng", - "y": 205560 - }, - { - "custom": { - "xLabel": "Toyama", - "yLabel": "325 790" - }, - "category": "Toyama", - "y": 325790 - }, - { - "custom": { - "xLabel": "A Coruña (La Coruña)", - "yLabel": "243 402" - }, - "category": "A Coruña (La Coruña)", - "y": 243402 - }, - { - "custom": { - "xLabel": "Jessentuki", - "yLabel": "97 900" - }, - "category": "Jessentuki", - "y": 97900 - }, - { - "custom": { - "xLabel": "Shahrud", - "yLabel": "104 765" - }, - "category": "Shahrud", - "y": 104765 - }, - { - "custom": { - "xLabel": "Bally", - "yLabel": "184 474" - }, - "category": "Bally", - "y": 184474 - }, - { - "custom": { - "xLabel": "Merlo", - "yLabel": "463 846" - }, - "category": "Merlo", - "y": 463846 - }, - { - "custom": { - "xLabel": "Yamagata", - "yLabel": "255 617" - }, - "category": "Yamagata", - "y": 255617 - }, - { - "custom": { - "xLabel": "Ila", - "yLabel": "264 000" - }, - "category": "Ila", - "y": 264000 - }, - { - "custom": { - "xLabel": "Raipur", - "yLabel": "438 639" - }, - "category": "Raipur", - "y": 438639 - }, - { - "custom": { - "xLabel": "Resistencia", - "yLabel": "229 212" - }, - "category": "Resistencia", - "y": 229212 - }, - { - "custom": { - "xLabel": "Huaying", - "yLabel": "89 400" - }, - "category": "Huaying", - "y": 89400 - }, - { - "custom": { - "xLabel": "Barrie", - "yLabel": "89 269" - }, - "category": "Barrie", - "y": 89269 - }, - { - "custom": { - "xLabel": "Castellón de la Plana [Castell", - "yLabel": "139 712" - }, - "category": "Castellón de la Plana [Castell", - "y": 139712 - }, - { - "custom": { - "xLabel": "Rishra", - "yLabel": "102 649" - }, - "category": "Rishra", - "y": 102649 - }, - { - "custom": { - "xLabel": "Clermont-Ferrand", - "yLabel": "137 140" - }, - "category": "Clermont-Ferrand", - "y": 137140 - }, - { - "custom": { - "xLabel": "Oyo", - "yLabel": "256 400" - }, - "category": "Oyo", - "y": 256400 - }, - { - "custom": { - "xLabel": "Divinópolis", - "yLabel": "185 047" - }, - "category": "Divinópolis", - "y": 185047 - }, - { - "custom": { - "xLabel": "Bandar-e Anzali", - "yLabel": "98 500" - }, - "category": "Bandar-e Anzali", - "y": 98500 - }, - { - "custom": { - "xLabel": "Chatsworth", - "yLabel": "189 885" - }, - "category": "Chatsworth", - "y": 189885 - }, - { - "custom": { - "xLabel": "Haeju", - "yLabel": "229 172" - }, - "category": "Haeju", - "y": 229172 - }, - { - "custom": { - "xLabel": "São Tomé", - "yLabel": "49 541" - }, - "category": "São Tomé", - "y": 49541 - }, - { - "custom": { - "xLabel": "Diourbel", - "yLabel": "99 400" - }, - "category": "Diourbel", - "y": 99400 - }, - { - "custom": { - "xLabel": "Bonn", - "yLabel": "301 048" - }, - "category": "Bonn", - "y": 301048 - }, - { - "custom": { - "xLabel": "Daito", - "yLabel": "130 594" - }, - "category": "Daito", - "y": 130594 - }, - { - "custom": { - "xLabel": "Salvatierra", - "yLabel": "94 322" - }, - "category": "Salvatierra", - "y": 94322 - }, - { - "custom": { - "xLabel": "Silchar", - "yLabel": "115 483" - }, - "category": "Silchar", - "y": 115483 - }, - { - "custom": { - "xLabel": "Zhongshan", - "yLabel": "278 829" - }, - "category": "Zhongshan", - "y": 278829 - }, - { - "custom": { - "xLabel": "Paju", - "yLabel": "163 379" - }, - "category": "Paju", - "y": 163379 - }, - { - "custom": { - "xLabel": "Kumamoto", - "yLabel": "656 734" - }, - "category": "Kumamoto", - "y": 656734 - }, - { - "custom": { - "xLabel": "Tegucigalpa", - "yLabel": "813 900" - }, - "category": "Tegucigalpa", - "y": 813900 - }, - { - "custom": { - "xLabel": "Durban", - "yLabel": "566 120" - }, - "category": "Durban", - "y": 566120 - }, - { - "custom": { - "xLabel": "Cape Coral", - "yLabel": "102 286" - }, - "category": "Cape Coral", - "y": 102286 - }, - { - "custom": { - "xLabel": "Tirunelveli", - "yLabel": "135 825" - }, - "category": "Tirunelveli", - "y": 135825 - }, - { - "custom": { - "xLabel": "Arrah (Ara)", - "yLabel": "157 082" - }, - "category": "Arrah (Ara)", - "y": 157082 - }, - { - "custom": { - "xLabel": "Hamilton", - "yLabel": "1 200" - }, - "category": "Hamilton", - "y": 1200 - }, - { - "custom": { - "xLabel": "General San Martín", - "yLabel": "422 542" - }, - "category": "General San Martín", - "y": 422542 - }, - { - "custom": { - "xLabel": "Dar es Salaam", - "yLabel": "1 747 000" - }, - "category": "Dar es Salaam", - "y": 1747000 - }, - { - "custom": { - "xLabel": "Zhangjiang", - "yLabel": "400 997" - }, - "category": "Zhangjiang", - "y": 400997 - }, - { - "custom": { - "xLabel": "Pallavaram", - "yLabel": "111 866" - }, - "category": "Pallavaram", - "y": 111866 - }, - { - "custom": { - "xLabel": "Nashville-Davidson", - "yLabel": "569 891" - }, - "category": "Nashville-Davidson", - "y": 569891 - }, - { - "custom": { - "xLabel": "Cartagena", - "yLabel": "805 757" - }, - "category": "Cartagena", - "y": 805757 - }, - { - "custom": { - "xLabel": "Ancona", - "yLabel": "98 329" - }, - "category": "Ancona", - "y": 98329 - }, - { - "custom": { - "xLabel": "Lexington-Fayette", - "yLabel": "260 512" - }, - "category": "Lexington-Fayette", - "y": 260512 - }, - { - "custom": { - "xLabel": "Mathura", - "yLabel": "226 691" - }, - "category": "Mathura", - "y": 226691 - }, - { - "custom": { - "xLabel": "São Bernardo do Campo", - "yLabel": "723 132" - }, - "category": "São Bernardo do Campo", - "y": 723132 - }, - { - "custom": { - "xLabel": "Granada", - "yLabel": "244 767" - }, - "category": "Granada", - "y": 244767 - }, - { - "custom": { - "xLabel": "Rotterdam", - "yLabel": "593 321" - }, - "category": "Rotterdam", - "y": 593321 - }, - { - "custom": { - "xLabel": "Genova", - "yLabel": "636 104" - }, - "category": "Genova", - "y": 636104 - }, - { - "custom": { - "xLabel": "Saanich", - "yLabel": "101 388" - }, - "category": "Saanich", - "y": 101388 - }, - { - "custom": { - "xLabel": "Mandi Burewala", - "yLabel": "149 900" - }, - "category": "Mandi Burewala", - "y": 149900 - }, - { - "custom": { - "xLabel": "Ilan", - "yLabel": "92 000" - }, - "category": "Ilan", - "y": 92000 - }, - { - "custom": { - "xLabel": "Gulbarga", - "yLabel": "304 099" - }, - "category": "Gulbarga", - "y": 304099 - }, - { - "custom": { - "xLabel": "Orenburg", - "yLabel": "523 600" - }, - "category": "Orenburg", - "y": 523600 - }, - { - "custom": { - "xLabel": "Fujinomiya", - "yLabel": "119 714" - }, - "category": "Fujinomiya", - "y": 119714 - }, - { - "custom": { - "xLabel": "Hyesan", - "yLabel": "178 020" - }, - "category": "Hyesan", - "y": 178020 - }, - { - "custom": { - "xLabel": "Saint-Louis", - "yLabel": "132 400" - }, - "category": "Saint-Louis", - "y": 132400 - }, - { - "custom": { - "xLabel": "Birmingham", - "yLabel": "1 013 000" - }, - "category": "Birmingham", - "y": 1013000 - }, - { - "custom": { - "xLabel": "El Fuerte", - "yLabel": "89 556" - }, - "category": "El Fuerte", - "y": 89556 - }, - { - "custom": { - "xLabel": "Arlington", - "yLabel": "174 838" - }, - "category": "Arlington", - "y": 174838 - }, - { - "custom": { - "xLabel": "Ventanilla", - "yLabel": "101 056" - }, - "category": "Ventanilla", - "y": 101056 - }, - { - "custom": { - "xLabel": "Guadalajara", - "yLabel": "1 647 720" - }, - "category": "Guadalajara", - "y": 1647720 - }, - { - "custom": { - "xLabel": "Jelenia Góra", - "yLabel": "93 901" - }, - "category": "Jelenia Góra", - "y": 93901 - }, - { - "custom": { - "xLabel": "Roxas", - "yLabel": "126 352" - }, - "category": "Roxas", - "y": 126352 - }, - { - "custom": { - "xLabel": "Malvinas Argentinas", - "yLabel": "290 335" - }, - "category": "Malvinas Argentinas", - "y": 290335 - }, - { - "custom": { - "xLabel": "Banda Aceh", - "yLabel": "143 409" - }, - "category": "Banda Aceh", - "y": 143409 - }, - { - "custom": { - "xLabel": "Rio Branco", - "yLabel": "259 537" - }, - "category": "Rio Branco", - "y": 259537 - }, - { - "custom": { - "xLabel": "Holguín", - "yLabel": "249 492" - }, - "category": "Holguín", - "y": 249492 - }, - { - "custom": { - "xLabel": "Shiraz", - "yLabel": "1 053 025" - }, - "category": "Shiraz", - "y": 1053025 - }, - { - "custom": { - "xLabel": "Rae Bareli", - "yLabel": "129 904" - }, - "category": "Rae Bareli", - "y": 129904 - }, - { - "custom": { - "xLabel": "Fukui", - "yLabel": "254 818" - }, - "category": "Fukui", - "y": 254818 - }, - { - "custom": { - "xLabel": "Kamakura", - "yLabel": "167 661" - }, - "category": "Kamakura", - "y": 167661 - }, - { - "custom": { - "xLabel": "Satara", - "yLabel": "95 133" - }, - "category": "Satara", - "y": 95133 - }, - { - "custom": { - "xLabel": "Depok", - "yLabel": "365 200" - }, - "category": "Depok", - "y": 365200 - }, - { - "custom": { - "xLabel": "Maracanaú", - "yLabel": "162 022" - }, - "category": "Maracanaú", - "y": 162022 - }, - { - "custom": { - "xLabel": "Aachen", - "yLabel": "243 825" - }, - "category": "Aachen", - "y": 243825 - }, - { - "custom": { - "xLabel": "Campeche", - "yLabel": "216 735" - }, - "category": "Campeche", - "y": 216735 - }, - { - "custom": { - "xLabel": "San Miguel", - "yLabel": "123 824" - }, - "category": "San Miguel", - "y": 123824 - }, - { - "custom": { - "xLabel": "Kota Bharu", - "yLabel": "219 582" - }, - "category": "Kota Bharu", - "y": 219582 - }, - { - "custom": { - "xLabel": "Salzburg", - "yLabel": "144 247" - }, - "category": "Salzburg", - "y": 144247 - }, - { - "custom": { - "xLabel": "Sundsvall", - "yLabel": "93 126" - }, - "category": "Sundsvall", - "y": 93126 - }, - { - "custom": { - "xLabel": "Arvada", - "yLabel": "102 153" - }, - "category": "Arvada", - "y": 102153 - }, - { - "custom": { - "xLabel": "Duma", - "yLabel": "131 158" - }, - "category": "Duma", - "y": 131158 - }, - { - "custom": { - "xLabel": "Campo Largo", - "yLabel": "91 203" - }, - "category": "Campo Largo", - "y": 91203 - }, - { - "custom": { - "xLabel": "Bratsk", - "yLabel": "277 600" - }, - "category": "Bratsk", - "y": 277600 - }, - { - "custom": { - "xLabel": "Abu Dhabi", - "yLabel": "398 695" - }, - "category": "Abu Dhabi", - "y": 398695 - }, - { - "custom": { - "xLabel": "Allende", - "yLabel": "134 645" - }, - "category": "Allende", - "y": 134645 - }, - { - "custom": { - "xLabel": "Ulsan", - "yLabel": "1 084 891" - }, - "category": "Ulsan", - "y": 1084891 - }, - { - "custom": { - "xLabel": "Mamoutzou", - "yLabel": "12 000" - }, - "category": "Mamoutzou", - "y": 12000 - }, - { - "custom": { - "xLabel": "Bose", - "yLabel": "93 009" - }, - "category": "Bose", - "y": 93009 - }, - { - "custom": { - "xLabel": "Tacloban", - "yLabel": "178 639" - }, - "category": "Tacloban", - "y": 178639 - }, - { - "custom": { - "xLabel": "Schaerbeek", - "yLabel": "105 692" - }, - "category": "Schaerbeek", - "y": 105692 - }, - { - "custom": { - "xLabel": "Agadir", - "yLabel": "155 244" - }, - "category": "Agadir", - "y": 155244 - }, - { - "custom": { - "xLabel": "Barretos", - "yLabel": "104 156" - }, - "category": "Barretos", - "y": 104156 - }, - { - "custom": { - "xLabel": "Gonda", - "yLabel": "106 078" - }, - "category": "Gonda", - "y": 106078 - }, - { - "custom": { - "xLabel": "Taiping", - "yLabel": "183 261" - }, - "category": "Taiping", - "y": 183261 - }, - { - "custom": { - "xLabel": "Marikina", - "yLabel": "391 170" - }, - "category": "Marikina", - "y": 391170 - }, - { - "custom": { - "xLabel": "Wazirabad", - "yLabel": "89 700" - }, - "category": "Wazirabad", - "y": 89700 - }, - { - "custom": { - "xLabel": "Boulogne-Billancourt", - "yLabel": "106 367" - }, - "category": "Boulogne-Billancourt", - "y": 106367 - }, - { - "custom": { - "xLabel": "Wonderboom", - "yLabel": "283 289" - }, - "category": "Wonderboom", - "y": 283289 - }, - { - "custom": { - "xLabel": "Gilbert", - "yLabel": "109 697" - }, - "category": "Gilbert", - "y": 109697 - }, - { - "custom": { - "xLabel": "Circik", - "yLabel": "146 400" - }, - "category": "Circik", - "y": 146400 - }, - { - "custom": { - "xLabel": "Castanhal", - "yLabel": "127 634" - }, - "category": "Castanhal", - "y": 127634 - }, - { - "custom": { - "xLabel": "Manila", - "yLabel": "1 581 082" - }, - "category": "Manila", - "y": 1581082 - }, - { - "custom": { - "xLabel": "Sevilla", - "yLabel": "701 927" - }, - "category": "Sevilla", - "y": 701927 - }, - { - "custom": { - "xLabel": "Medellín", - "yLabel": "1 861 265" - }, - "category": "Medellín", - "y": 1861265 - }, - { - "custom": { - "xLabel": "Navoi", - "yLabel": "116 300" - }, - "category": "Navoi", - "y": 116300 - }, - { - "custom": { - "xLabel": "Delta", - "yLabel": "95 411" - }, - "category": "Delta", - "y": 95411 - }, - { - "custom": { - "xLabel": "Pingtung", - "yLabel": "214 727" - }, - "category": "Pingtung", - "y": 214727 - }, - { - "custom": { - "xLabel": "Tsukuba", - "yLabel": "160 768" - }, - "category": "Tsukuba", - "y": 160768 - }, - { - "custom": { - "xLabel": "Nilópolis", - "yLabel": "153 383" - }, - "category": "Nilópolis", - "y": 153383 - }, - { - "custom": { - "xLabel": "Taiping", - "yLabel": "165 524" - }, - "category": "Taiping", - "y": 165524 - }, - { - "custom": { - "xLabel": "Newcastle", - "yLabel": "270 324" - }, - "category": "Newcastle", - "y": 270324 - }, - { - "custom": { - "xLabel": "Thimphu", - "yLabel": "22 000" - }, - "category": "Thimphu", - "y": 22000 - }, - { - "custom": { - "xLabel": "Atibaia", - "yLabel": "100 356" - }, - "category": "Atibaia", - "y": 100356 - }, - { - "custom": { - "xLabel": "Santa Cruz do Sul", - "yLabel": "106 734" - }, - "category": "Santa Cruz do Sul", - "y": 106734 - }, - { - "custom": { - "xLabel": "Xuchang", - "yLabel": "208 815" - }, - "category": "Xuchang", - "y": 208815 - }, - { - "custom": { - "xLabel": "Puerto Montt", - "yLabel": "152 194" - }, - "category": "Puerto Montt", - "y": 152194 - }, - { - "custom": { - "xLabel": "Neiva", - "yLabel": "300 052" - }, - "category": "Neiva", - "y": 300052 - }, - { - "custom": { - "xLabel": "Ede", - "yLabel": "101 574" - }, - "category": "Ede", - "y": 101574 - }, - { - "custom": { - "xLabel": "Hsinchuang", - "yLabel": "365 048" - }, - "category": "Hsinchuang", - "y": 365048 - }, - { - "custom": { - "xLabel": "Bauru", - "yLabel": "313 670" - }, - "category": "Bauru", - "y": 313670 - }, - { - "custom": { - "xLabel": "Chaguanas", - "yLabel": "56 601" - }, - "category": "Chaguanas", - "y": 56601 - }, - { - "custom": { - "xLabel": "Pekalongan", - "yLabel": "301 504" - }, - "category": "Pekalongan", - "y": 301504 - }, - { - "custom": { - "xLabel": "[San Cristóbal de] la Laguna", - "yLabel": "127 945" - }, - "category": "[San Cristóbal de] la Laguna", - "y": 127945 - }, - { - "custom": { - "xLabel": "Narita", - "yLabel": "91 470" - }, - "category": "Narita", - "y": 91470 - }, - { - "custom": { - "xLabel": "Shijiazhuang", - "yLabel": "2 041 500" - }, - "category": "Shijiazhuang", - "y": 2041500 - }, - { - "custom": { - "xLabel": "Latina", - "yLabel": "114 099" - }, - "category": "Latina", - "y": 114099 - }, - { - "custom": { - "xLabel": "Offa", - "yLabel": "197 200" - }, - "category": "Offa", - "y": 197200 - }, - { - "custom": { - "xLabel": "Langfang", - "yLabel": "148 105" - }, - "category": "Langfang", - "y": 148105 - }, - { - "custom": { - "xLabel": "Cangzhou", - "yLabel": "242 708" - }, - "category": "Cangzhou", - "y": 242708 - }, - { - "custom": { - "xLabel": "Salé", - "yLabel": "504 420" - }, - "category": "Salé", - "y": 504420 - }, - { - "custom": { - "xLabel": "Lapu-Lapu", - "yLabel": "217 019" - }, - "category": "Lapu-Lapu", - "y": 217019 - }, - { - "custom": { - "xLabel": "Saint John´s", - "yLabel": "24 000" - }, - "category": "Saint John´s", - "y": 24000 - }, - { - "custom": { - "xLabel": "Pingchen", - "yLabel": "188 344" - }, - "category": "Pingchen", - "y": 188344 - }, - { - "custom": { - "xLabel": "Herson", - "yLabel": "353 000" - }, - "category": "Herson", - "y": 353000 - }, - { - "custom": { - "xLabel": "Livorno", - "yLabel": "161 673" - }, - "category": "Livorno", - "y": 161673 - }, - { - "custom": { - "xLabel": "Jaunpur", - "yLabel": "136 062" - }, - "category": "Jaunpur", - "y": 136062 - }, - { - "custom": { - "xLabel": "Cimahi", - "yLabel": "344 600" - }, - "category": "Cimahi", - "y": 344600 - }, - { - "custom": { - "xLabel": "Sabzevar", - "yLabel": "170 738" - }, - "category": "Sabzevar", - "y": 170738 - }, - { - "custom": { - "xLabel": "Sultanbeyli", - "yLabel": "211 068" - }, - "category": "Sultanbeyli", - "y": 211068 - }, - { - "custom": { - "xLabel": "Awka", - "yLabel": "111 200" - }, - "category": "Awka", - "y": 111200 - }, - { - "custom": { - "xLabel": "Itaquaquecetuba", - "yLabel": "270 874" - }, - "category": "Itaquaquecetuba", - "y": 270874 - }, - { - "custom": { - "xLabel": "Dujiangyan", - "yLabel": "123 357" - }, - "category": "Dujiangyan", - "y": 123357 - }, - { - "custom": { - "xLabel": "Libreville", - "yLabel": "419 000" - }, - "category": "Libreville", - "y": 419000 - }, - { - "custom": { - "xLabel": "Maicao", - "yLabel": "108 053" - }, - "category": "Maicao", - "y": 108053 - }, - { - "custom": { - "xLabel": "Veliki Novgorod", - "yLabel": "299 500" - }, - "category": "Veliki Novgorod", - "y": 299500 - }, - { - "custom": { - "xLabel": "Cachoeirinha", - "yLabel": "103 240" - }, - "category": "Cachoeirinha", - "y": 103240 - }, - { - "custom": { - "xLabel": "Konya", - "yLabel": "628 364" - }, - "category": "Konya", - "y": 628364 - }, - { - "custom": { - "xLabel": "Tlemcen (Tilimsen)", - "yLabel": "110 242" - }, - "category": "Tlemcen (Tilimsen)", - "y": 110242 - }, - { - "custom": { - "xLabel": "Kusti", - "yLabel": "173 599" - }, - "category": "Kusti", - "y": 173599 - }, - { - "custom": { - "xLabel": "Krugersdorp", - "yLabel": "181 503" - }, - "category": "Krugersdorp", - "y": 181503 - }, - { - "custom": { - "xLabel": "Long Beach", - "yLabel": "461 522" - }, - "category": "Long Beach", - "y": 461522 - }, - { - "custom": { - "xLabel": "Ji-Paraná", - "yLabel": "93 346" - }, - "category": "Ji-Paraná", - "y": 93346 - }, - { - "custom": { - "xLabel": "Culiacán", - "yLabel": "744 859" - }, - "category": "Culiacán", - "y": 744859 - }, - { - "custom": { - "xLabel": "Bahir Dar", - "yLabel": "96 140" - }, - "category": "Bahir Dar", - "y": 96140 - }, - { - "custom": { - "xLabel": "Peterborough", - "yLabel": "156 000" - }, - "category": "Peterborough", - "y": 156000 - }, - { - "custom": { - "xLabel": "Campina Grande", - "yLabel": "352 497" - }, - "category": "Campina Grande", - "y": 352497 - }, - { - "custom": { - "xLabel": "Hail", - "yLabel": "176 800" - }, - "category": "Hail", - "y": 176800 - }, - { - "custom": { - "xLabel": "Tunja", - "yLabel": "109 740" - }, - "category": "Tunja", - "y": 109740 - }, - { - "custom": { - "xLabel": "Yantai", - "yLabel": "452 127" - }, - "category": "Yantai", - "y": 452127 - }, - { - "custom": { - "xLabel": "Vijayawada", - "yLabel": "701 827" - }, - "category": "Vijayawada", - "y": 701827 - }, - { - "custom": { - "xLabel": "Bat Yam", - "yLabel": "137 000" - }, - "category": "Bat Yam", - "y": 137000 - }, - { - "custom": { - "xLabel": "Bidar", - "yLabel": "108 016" - }, - "category": "Bidar", - "y": 108016 - }, - { - "custom": { - "xLabel": "Glazov", - "yLabel": "106 300" - }, - "category": "Glazov", - "y": 106300 - }, - { - "custom": { - "xLabel": "Nakhon Ratchasima", - "yLabel": "181 400" - }, - "category": "Nakhon Ratchasima", - "y": 181400 - }, - { - "custom": { - "xLabel": "Mingora", - "yLabel": "174 500" - }, - "category": "Mingora", - "y": 174500 - }, - { - "custom": { - "xLabel": "Mulhouse", - "yLabel": "110 359" - }, - "category": "Mulhouse", - "y": 110359 - }, - { - "custom": { - "xLabel": "Khomeynishahr", - "yLabel": "165 888" - }, - "category": "Khomeynishahr", - "y": 165888 - }, - { - "custom": { - "xLabel": "al-Mahallat al-Kubra", - "yLabel": "395 402" - }, - "category": "al-Mahallat al-Kubra", - "y": 395402 - }, - { - "custom": { - "xLabel": "Valencia", - "yLabel": "739 412" - }, - "category": "Valencia", - "y": 739412 - }, - { - "custom": { - "xLabel": "Nuuk", - "yLabel": "13 445" - }, - "category": "Nuuk", - "y": 13445 - }, - { - "custom": { - "xLabel": "Sialkot", - "yLabel": "417 597" - }, - "category": "Sialkot", - "y": 417597 - }, - { - "custom": { - "xLabel": "Ome", - "yLabel": "139 216" - }, - "category": "Ome", - "y": 139216 - }, - { - "custom": { - "xLabel": "Miass", - "yLabel": "166 200" - }, - "category": "Miass", - "y": 166200 - }, - { - "custom": { - "xLabel": "Zhaodong", - "yLabel": "179 976" - }, - "category": "Zhaodong", - "y": 179976 - }, - { - "custom": { - "xLabel": "Santa Rita", - "yLabel": "113 135" - }, - "category": "Santa Rita", - "y": 113135 - }, - { - "custom": { - "xLabel": "Djibouti", - "yLabel": "383 000" - }, - "category": "Djibouti", - "y": 383000 - }, - { - "custom": { - "xLabel": "Weifang", - "yLabel": "428 522" - }, - "category": "Weifang", - "y": 428522 - }, - { - "custom": { - "xLabel": "Maebashi", - "yLabel": "284 473" - }, - "category": "Maebashi", - "y": 284473 - }, - { - "custom": { - "xLabel": "Nasugbu", - "yLabel": "96 113" - }, - "category": "Nasugbu", - "y": 96113 - }, - { - "custom": { - "xLabel": "Aracaju", - "yLabel": "445 555" - }, - "category": "Aracaju", - "y": 445555 - }, - { - "custom": { - "xLabel": "Santa Maria", - "yLabel": "144 282" - }, - "category": "Santa Maria", - "y": 144282 - }, - { - "custom": { - "xLabel": "Fushun", - "yLabel": "1 200 000" - }, - "category": "Fushun", - "y": 1200000 - }, - { - "custom": { - "xLabel": "Gäncä", - "yLabel": "299 300" - }, - "category": "Gäncä", - "y": 299300 - }, - { - "custom": { - "xLabel": "Hatay (Antakya)", - "yLabel": "143 982" - }, - "category": "Hatay (Antakya)", - "y": 143982 - }, - { - "custom": { - "xLabel": "N´Djaména", - "yLabel": "530 965" - }, - "category": "N´Djaména", - "y": 530965 - }, - { - "custom": { - "xLabel": "Namibe", - "yLabel": "118 200" - }, - "category": "Namibe", - "y": 118200 - }, - { - "custom": { - "xLabel": "Camaragibe", - "yLabel": "118 968" - }, - "category": "Camaragibe", - "y": 118968 - }, - { - "custom": { - "xLabel": "Dese", - "yLabel": "97 314" - }, - "category": "Dese", - "y": 97314 - }, - { - "custom": { - "xLabel": "Jaipur", - "yLabel": "1 458 483" - }, - "category": "Jaipur", - "y": 1458483 - }, - { - "custom": { - "xLabel": "Gurgaon", - "yLabel": "128 608" - }, - "category": "Gurgaon", - "y": 128608 - }, - { - "custom": { - "xLabel": "Colombo", - "yLabel": "177 764" - }, - "category": "Colombo", - "y": 177764 - }, - { - "custom": { - "xLabel": "Osmaniye", - "yLabel": "146 003" - }, - "category": "Osmaniye", - "y": 146003 - }, - { - "custom": { - "xLabel": "Biratnagar", - "yLabel": "157 764" - }, - "category": "Biratnagar", - "y": 157764 - }, - { - "custom": { - "xLabel": "Jalandhar (Jullundur)", - "yLabel": "509 510" - }, - "category": "Jalandhar (Jullundur)", - "y": 509510 - }, - { - "custom": { - "xLabel": "Sorocaba", - "yLabel": "466 823" - }, - "category": "Sorocaba", - "y": 466823 - }, - { - "custom": { - "xLabel": "Baghdad", - "yLabel": "4 336 000" - }, - "category": "Baghdad", - "y": 4336000 - }, - { - "custom": { - "xLabel": "Iksan", - "yLabel": "322 685" - }, - "category": "Iksan", - "y": 322685 - }, - { - "custom": { - "xLabel": "Saint John´s", - "yLabel": "101 936" - }, - "category": "Saint John´s", - "y": 101936 - }, - { - "custom": { - "xLabel": "Split", - "yLabel": "189 388" - }, - "category": "Split", - "y": 189388 - }, - { - "custom": { - "xLabel": "Ústí nad Labem", - "yLabel": "95 491" - }, - "category": "Ústí nad Labem", - "y": 95491 - }, - { - "custom": { - "xLabel": "Ulan-Ude", - "yLabel": "370 400" - }, - "category": "Ulan-Ude", - "y": 370400 - }, - { - "custom": { - "xLabel": "al-Najaf", - "yLabel": "309 010" - }, - "category": "al-Najaf", - "y": 309010 - }, - { - "custom": { - "xLabel": "Kimhae", - "yLabel": "256 370" - }, - "category": "Kimhae", - "y": 256370 - }, - { - "custom": { - "xLabel": "Karsi", - "yLabel": "194 100" - }, - "category": "Karsi", - "y": 194100 - }, - { - "custom": { - "xLabel": "Slovjansk", - "yLabel": "127 000" - }, - "category": "Slovjansk", - "y": 127000 - }, - { - "custom": { - "xLabel": "Laval", - "yLabel": "330 393" - }, - "category": "Laval", - "y": 330393 - }, - { - "custom": { - "xLabel": "Saarbrücken", - "yLabel": "183 836" - }, - "category": "Saarbrücken", - "y": 183836 - }, - { - "custom": { - "xLabel": "Trento", - "yLabel": "104 906" - }, - "category": "Trento", - "y": 104906 - }, - { - "custom": { - "xLabel": "Mutare", - "yLabel": "131 367" - }, - "category": "Mutare", - "y": 131367 - }, - { - "custom": { - "xLabel": "Kansas City", - "yLabel": "146 866" - }, - "category": "Kansas City", - "y": 146866 - }, - { - "custom": { - "xLabel": "Nagasaki", - "yLabel": "432 759" - }, - "category": "Nagasaki", - "y": 432759 - }, - { - "custom": { - "xLabel": "Ilorin", - "yLabel": "475 800" - }, - "category": "Ilorin", - "y": 475800 - }, - { - "custom": { - "xLabel": "Liangcheng", - "yLabel": "156 307" - }, - "category": "Liangcheng", - "y": 156307 - }, - { - "custom": { - "xLabel": "Shimizu", - "yLabel": "239 123" - }, - "category": "Shimizu", - "y": 239123 - }, - { - "custom": { - "xLabel": "Garanhuns", - "yLabel": "114 603" - }, - "category": "Garanhuns", - "y": 114603 - }, - { - "custom": { - "xLabel": "Tema", - "yLabel": "109 975" - }, - "category": "Tema", - "y": 109975 - }, - { - "custom": { - "xLabel": "Sosan", - "yLabel": "134 746" - }, - "category": "Sosan", - "y": 134746 - }, - { - "custom": { - "xLabel": "Krasnogorsk", - "yLabel": "91 000" - }, - "category": "Krasnogorsk", - "y": 91000 - }, - { - "custom": { - "xLabel": "Ningbo", - "yLabel": "1 371 200" - }, - "category": "Ningbo", - "y": 1371200 - }, - { - "custom": { - "xLabel": "Alcalá de Henares", - "yLabel": "164 463" - }, - "category": "Alcalá de Henares", - "y": 164463 - }, - { - "custom": { - "xLabel": "Hualien", - "yLabel": "108 407" - }, - "category": "Hualien", - "y": 108407 - }, - { - "custom": { - "xLabel": "Carmen", - "yLabel": "171 367" - }, - "category": "Carmen", - "y": 171367 - }, - { - "custom": { - "xLabel": "Ciudad de México", - "yLabel": "8 591 309" - }, - "category": "Ciudad de México", - "y": 8591309 - }, - { - "custom": { - "xLabel": "Posadas", - "yLabel": "201 273" - }, - "category": "Posadas", - "y": 201273 - }, - { - "custom": { - "xLabel": "Uppsala", - "yLabel": "189 569" - }, - "category": "Uppsala", - "y": 189569 - }, - { - "custom": { - "xLabel": "San Fernando", - "yLabel": "221 857" - }, - "category": "San Fernando", - "y": 221857 - }, - { - "custom": { - "xLabel": "Bukan", - "yLabel": "120 020" - }, - "category": "Bukan", - "y": 120020 - }, - { - "custom": { - "xLabel": "San Felipe de Puerto Plata", - "yLabel": "89 423" - }, - "category": "San Felipe de Puerto Plata", - "y": 89423 - }, - { - "custom": { - "xLabel": "Vorkuta", - "yLabel": "92 600" - }, - "category": "Vorkuta", - "y": 92600 - }, - { - "custom": { - "xLabel": "Callao", - "yLabel": "424 294" - }, - "category": "Callao", - "y": 424294 - }, - { - "custom": { - "xLabel": "Bento Gonçalves", - "yLabel": "89 254" - }, - "category": "Bento Gonçalves", - "y": 89254 - }, - { - "custom": { - "xLabel": "Bida", - "yLabel": "125 500" - }, - "category": "Bida", - "y": 125500 - }, - { - "custom": { - "xLabel": "Dalap-Uliga-Darrit", - "yLabel": "28 000" - }, - "category": "Dalap-Uliga-Darrit", - "y": 28000 - }, - { - "custom": { - "xLabel": "Sayama", - "yLabel": "162 472" - }, - "category": "Sayama", - "y": 162472 - }, - { - "custom": { - "xLabel": "Riga", - "yLabel": "764 328" - }, - "category": "Riga", - "y": 764328 - }, - { - "custom": { - "xLabel": "Jamalpur", - "yLabel": "103 556" - }, - "category": "Jamalpur", - "y": 103556 - }, - { - "custom": { - "xLabel": "Mesquite", - "yLabel": "124 523" - }, - "category": "Mesquite", - "y": 124523 - }, - { - "custom": { - "xLabel": "Beni-Mellal", - "yLabel": "140 212" - }, - "category": "Beni-Mellal", - "y": 140212 - }, - { - "custom": { - "xLabel": "Ariana", - "yLabel": "197 000" - }, - "category": "Ariana", - "y": 197000 - }, - { - "custom": { - "xLabel": "Kimitsu", - "yLabel": "93 216" - }, - "category": "Kimitsu", - "y": 93216 - }, - { - "custom": { - "xLabel": "Zhangjiakou", - "yLabel": "530 000" - }, - "category": "Zhangjiakou", - "y": 530000 - }, - { - "custom": { - "xLabel": "Jaraguá do Sul", - "yLabel": "102 580" - }, - "category": "Jaraguá do Sul", - "y": 102580 - }, - { - "custom": { - "xLabel": "Viamão", - "yLabel": "207 557" - }, - "category": "Viamão", - "y": 207557 - }, - { - "custom": { - "xLabel": "Zukovski", - "yLabel": "96 500" - }, - "category": "Zukovski", - "y": 96500 - }, - { - "custom": { - "xLabel": "Muzaffarnagar", - "yLabel": "240 609" - }, - "category": "Muzaffarnagar", - "y": 240609 - }, - { - "custom": { - "xLabel": "Chishtian Mandi", - "yLabel": "101 700" - }, - "category": "Chishtian Mandi", - "y": 101700 - }, - { - "custom": { - "xLabel": "Pusan", - "yLabel": "3 804 522" - }, - "category": "Pusan", - "y": 3804522 - }, - { - "custom": { - "xLabel": "Delhi Cantonment", - "yLabel": "94 326" - }, - "category": "Delhi Cantonment", - "y": 94326 - }, - { - "custom": { - "xLabel": "Salvador", - "yLabel": "2 302 832" - }, - "category": "Salvador", - "y": 2302832 - }, - { - "custom": { - "xLabel": "Taguig", - "yLabel": "467 375" - }, - "category": "Taguig", - "y": 467375 - }, - { - "custom": { - "xLabel": "Yangjiang", - "yLabel": "215 196" - }, - "category": "Yangjiang", - "y": 215196 - }, - { - "custom": { - "xLabel": "Tšita", - "yLabel": "309 900" - }, - "category": "Tšita", - "y": 309900 - }, - { - "custom": { - "xLabel": "Kaohsiung", - "yLabel": "1 475 505" - }, - "category": "Kaohsiung", - "y": 1475505 - }, - { - "custom": { - "xLabel": "Khanewal", - "yLabel": "133 000" - }, - "category": "Khanewal", - "y": 133000 - }, - { - "custom": { - "xLabel": "Rjazan", - "yLabel": "529 900" - }, - "category": "Rjazan", - "y": 529900 - }, - { - "custom": { - "xLabel": "Beerseba", - "yLabel": "163 700" - }, - "category": "Beerseba", - "y": 163700 - }, - { - "custom": { - "xLabel": "Nakhon Pathom", - "yLabel": "94 100" - }, - "category": "Nakhon Pathom", - "y": 94100 - }, - { - "custom": { - "xLabel": "La Paz", - "yLabel": "196 708" - }, - "category": "La Paz", - "y": 196708 - }, - { - "custom": { - "xLabel": "Bhiwandi", - "yLabel": "379 070" - }, - "category": "Bhiwandi", - "y": 379070 - }, - { - "custom": { - "xLabel": "Majalaya", - "yLabel": "93 200" - }, - "category": "Majalaya", - "y": 93200 - }, - { - "custom": { - "xLabel": "Vereeniging", - "yLabel": "328 535" - }, - "category": "Vereeniging", - "y": 328535 - }, - { - "custom": { - "xLabel": "Coventry", - "yLabel": "304 000" - }, - "category": "Coventry", - "y": 304000 - }, - { - "custom": { - "xLabel": "Miskolc", - "yLabel": "172 357" - }, - "category": "Miskolc", - "y": 172357 - }, - { - "custom": { - "xLabel": "Karaman", - "yLabel": "104 200" - }, - "category": "Karaman", - "y": 104200 - }, - { - "custom": { - "xLabel": "Kolomna", - "yLabel": "150 700" - }, - "category": "Kolomna", - "y": 150700 - }, - { - "custom": { - "xLabel": "Venezia", - "yLabel": "277 305" - }, - "category": "Venezia", - "y": 277305 - }, - { - "custom": { - "xLabel": "Barueri", - "yLabel": "208 426" - }, - "category": "Barueri", - "y": 208426 - }, - { - "custom": { - "xLabel": "Noida", - "yLabel": "146 514" - }, - "category": "Noida", - "y": 146514 - }, - { - "custom": { - "xLabel": "Springs", - "yLabel": "162 072" - }, - "category": "Springs", - "y": 162072 - }, - { - "custom": { - "xLabel": "Khairpur", - "yLabel": "102 200" - }, - "category": "Khairpur", - "y": 102200 - }, - { - "custom": { - "xLabel": "Qutubullapur", - "yLabel": "105 380" - }, - "category": "Qutubullapur", - "y": 105380 - }, - { - "custom": { - "xLabel": "Salem", - "yLabel": "136 924" - }, - "category": "Salem", - "y": 136924 - }, - { - "custom": { - "xLabel": "Iquique", - "yLabel": "177 892" - }, - "category": "Iquique", - "y": 177892 - }, - { - "custom": { - "xLabel": "Ahome", - "yLabel": "358 663" - }, - "category": "Ahome", - "y": 358663 - }, - { - "custom": { - "xLabel": "Ilawe-Ekiti", - "yLabel": "184 500" - }, - "category": "Ilawe-Ekiti", - "y": 184500 - }, - { - "custom": { - "xLabel": "Subotica", - "yLabel": "100 386" - }, - "category": "Subotica", - "y": 100386 - }, - { - "custom": { - "xLabel": "Santa Cruz de Tenerife", - "yLabel": "213 050" - }, - "category": "Santa Cruz de Tenerife", - "y": 213050 - }, - { - "custom": { - "xLabel": "Saratov", - "yLabel": "874 000" - }, - "category": "Saratov", - "y": 874000 - }, - { - "custom": { - "xLabel": "Niamey", - "yLabel": "420 000" - }, - "category": "Niamey", - "y": 420000 - }, - { - "custom": { - "xLabel": "Kiel", - "yLabel": "233 795" - }, - "category": "Kiel", - "y": 233795 - }, - { - "custom": { - "xLabel": "Qingzhou", - "yLabel": "128 258" - }, - "category": "Qingzhou", - "y": 128258 - }, - { - "custom": { - "xLabel": "Mishan", - "yLabel": "132 744" - }, - "category": "Mishan", - "y": 132744 - }, - { - "custom": { - "xLabel": "Angren", - "yLabel": "128 000" - }, - "category": "Angren", - "y": 128000 - }, - { - "custom": { - "xLabel": "Brockton", - "yLabel": "93 653" - }, - "category": "Brockton", - "y": 93653 - }, - { - "custom": { - "xLabel": "Toa Baja", - "yLabel": "94 085" - }, - "category": "Toa Baja", - "y": 94085 - }, - { - "custom": { - "xLabel": "Dadu", - "yLabel": "98 600" - }, - "category": "Dadu", - "y": 98600 - }, - { - "custom": { - "xLabel": "Winston-Salem", - "yLabel": "185 776" - }, - "category": "Winston-Salem", - "y": 185776 - }, - { - "custom": { - "xLabel": "Chisinau", - "yLabel": "719 900" - }, - "category": "Chisinau", - "y": 719900 - }, - { - "custom": { - "xLabel": "Selayang Baru", - "yLabel": "124 228" - }, - "category": "Selayang Baru", - "y": 124228 - }, - { - "custom": { - "xLabel": "Semnan", - "yLabel": "91 045" - }, - "category": "Semnan", - "y": 91045 - }, - { - "custom": { - "xLabel": "Zenica", - "yLabel": "96 027" - }, - "category": "Zenica", - "y": 96027 - }, - { - "custom": { - "xLabel": "Metairie", - "yLabel": "149 428" - }, - "category": "Metairie", - "y": 149428 - }, - { - "custom": { - "xLabel": "Coimbatore", - "yLabel": "816 321" - }, - "category": "Coimbatore", - "y": 816321 - }, - { - "custom": { - "xLabel": "Honolulu", - "yLabel": "371 657" - }, - "category": "Honolulu", - "y": 371657 - }, - { - "custom": { - "xLabel": "San Nicolás de los Garza", - "yLabel": "495 540" - }, - "category": "San Nicolás de los Garza", - "y": 495540 - }, - { - "custom": { - "xLabel": "Panihati", - "yLabel": "275 990" - }, - "category": "Panihati", - "y": 275990 - }, - { - "custom": { - "xLabel": "Cunduacán", - "yLabel": "104 164" - }, - "category": "Cunduacán", - "y": 104164 - }, - { - "custom": { - "xLabel": "Ganganagar", - "yLabel": "161 482" - }, - "category": "Ganganagar", - "y": 161482 - }, - { - "custom": { - "xLabel": "Bhavnagar", - "yLabel": "402 338" - }, - "category": "Bhavnagar", - "y": 402338 - }, - { - "custom": { - "xLabel": "Jiaozhou", - "yLabel": "153 364" - }, - "category": "Jiaozhou", - "y": 153364 - }, - { - "custom": { - "xLabel": "Billings", - "yLabel": "92 988" - }, - "category": "Billings", - "y": 92988 - }, - { - "custom": { - "xLabel": "Hohhot", - "yLabel": "916 700" - }, - "category": "Hohhot", - "y": 916700 - }, - { - "custom": { - "xLabel": "Valparaíso", - "yLabel": "293 800" - }, - "category": "Valparaíso", - "y": 293800 - }, - { - "custom": { - "xLabel": "Armavir", - "yLabel": "164 900" - }, - "category": "Armavir", - "y": 164900 - }, - { - "custom": { - "xLabel": "Maracay", - "yLabel": "444 443" - }, - "category": "Maracay", - "y": 444443 - }, - { - "custom": { - "xLabel": "Idfu", - "yLabel": "94 200" - }, - "category": "Idfu", - "y": 94200 - }, - { - "custom": { - "xLabel": "Kathmandu", - "yLabel": "591 835" - }, - "category": "Kathmandu", - "y": 591835 - }, - { - "custom": { - "xLabel": "Kandy", - "yLabel": "140 000" - }, - "category": "Kandy", - "y": 140000 - }, - { - "custom": { - "xLabel": "Saint-Pierre", - "yLabel": "5 808" - }, - "category": "Saint-Pierre", - "y": 5808 - }, - { - "custom": { - "xLabel": "Taxco de Alarcón", - "yLabel": "99 907" - }, - "category": "Taxco de Alarcón", - "y": 99907 - }, - { - "custom": { - "xLabel": "Nowshera", - "yLabel": "89 400" - }, - "category": "Nowshera", - "y": 89400 - }, - { - "custom": { - "xLabel": "Salala", - "yLabel": "131 813" - }, - "category": "Salala", - "y": 131813 - }, - { - "custom": { - "xLabel": "Miryang", - "yLabel": "121 501" - }, - "category": "Miryang", - "y": 121501 - }, - { - "custom": { - "xLabel": "Shishou", - "yLabel": "104 571" - }, - "category": "Shishou", - "y": 104571 - }, - { - "custom": { - "xLabel": "Ussurijsk", - "yLabel": "157 300" - }, - "category": "Ussurijsk", - "y": 157300 - }, - { - "custom": { - "xLabel": "Gelsenkirchen", - "yLabel": "281 979" - }, - "category": "Gelsenkirchen", - "y": 281979 - }, - { - "custom": { - "xLabel": "Watford", - "yLabel": "113 080" - }, - "category": "Watford", - "y": 113080 - }, - { - "custom": { - "xLabel": "Cluj-Napoca", - "yLabel": "332 498" - }, - "category": "Cluj-Napoca", - "y": 332498 - }, - { - "custom": { - "xLabel": "al-Qamishliya", - "yLabel": "144 286" - }, - "category": "al-Qamishliya", - "y": 144286 - }, - { - "custom": { - "xLabel": "Kuwait", - "yLabel": "28 859" - }, - "category": "Kuwait", - "y": 28859 - }, - { - "custom": { - "xLabel": "Mysore", - "yLabel": "480 692" - }, - "category": "Mysore", - "y": 480692 - }, - { - "custom": { - "xLabel": "Manukau", - "yLabel": "281 800" - }, - "category": "Manukau", - "y": 281800 - }, - { - "custom": { - "xLabel": "Waco", - "yLabel": "113 726" - }, - "category": "Waco", - "y": 113726 - }, - { - "custom": { - "xLabel": "Shizuishan", - "yLabel": "257 862" - }, - "category": "Shizuishan", - "y": 257862 - }, - { - "custom": { - "xLabel": "Sabará", - "yLabel": "107 781" - }, - "category": "Sabará", - "y": 107781 - }, - { - "custom": { - "xLabel": "Giugliano in Campania", - "yLabel": "93 286" - }, - "category": "Giugliano in Campania", - "y": 93286 - }, - { - "custom": { - "xLabel": "Nairobi", - "yLabel": "2 290 000" - }, - "category": "Nairobi", - "y": 2290000 - }, - { - "custom": { - "xLabel": "Osh", - "yLabel": "222 700" - }, - "category": "Osh", - "y": 222700 - }, - { - "custom": { - "xLabel": "Uljanovsk", - "yLabel": "667 400" - }, - "category": "Uljanovsk", - "y": 667400 - }, - { - "custom": { - "xLabel": "Cachoeiro de Itapemirim", - "yLabel": "155 024" - }, - "category": "Cachoeiro de Itapemirim", - "y": 155024 - }, - { - "custom": { - "xLabel": "Lahti", - "yLabel": "96 921" - }, - "category": "Lahti", - "y": 96921 - }, - { - "custom": { - "xLabel": "Alcorcón", - "yLabel": "142 048" - }, - "category": "Alcorcón", - "y": 142048 - }, - { - "custom": { - "xLabel": "Phnom Penh", - "yLabel": "570 155" - }, - "category": "Phnom Penh", - "y": 570155 - }, - { - "custom": { - "xLabel": "Würzburg", - "yLabel": "127 350" - }, - "category": "Würzburg", - "y": 127350 - }, - { - "custom": { - "xLabel": "Mardan", - "yLabel": "244 511" - }, - "category": "Mardan", - "y": 244511 - }, - { - "custom": { - "xLabel": "Bobo-Dioulasso", - "yLabel": "300 000" - }, - "category": "Bobo-Dioulasso", - "y": 300000 - }, - { - "custom": { - "xLabel": "Bangalore", - "yLabel": "2 660 088" - }, - "category": "Bangalore", - "y": 2660088 - }, - { - "custom": { - "xLabel": "Santa Cruz", - "yLabel": "92 694" - }, - "category": "Santa Cruz", - "y": 92694 - }, - { - "custom": { - "xLabel": "Norilsk", - "yLabel": "140 800" - }, - "category": "Norilsk", - "y": 140800 - }, - { - "custom": { - "xLabel": "Hodeida", - "yLabel": "298 500" - }, - "category": "Hodeida", - "y": 298500 - }, - { - "custom": { - "xLabel": "Vidisha", - "yLabel": "92 917" - }, - "category": "Vidisha", - "y": 92917 - }, - { - "custom": { - "xLabel": "Soweto", - "yLabel": "904 165" - }, - "category": "Soweto", - "y": 904165 - }, - { - "custom": { - "xLabel": "Tokushima", - "yLabel": "269 649" - }, - "category": "Tokushima", - "y": 269649 - }, - { - "custom": { - "xLabel": "Macon", - "yLabel": "113 336" - }, - "category": "Macon", - "y": 113336 - }, - { - "custom": { - "xLabel": "Guilin", - "yLabel": "364 130" - }, - "category": "Guilin", - "y": 364130 - }, - { - "custom": { - "xLabel": "Meerut", - "yLabel": "753 778" - }, - "category": "Meerut", - "y": 753778 - }, - { - "custom": { - "xLabel": "Asmara", - "yLabel": "431 000" - }, - "category": "Asmara", - "y": 431000 - }, - { - "custom": { - "xLabel": "Bilbao", - "yLabel": "357 589" - }, - "category": "Bilbao", - "y": 357589 - }, - { - "custom": { - "xLabel": "Florencio Varela", - "yLabel": "315 432" - }, - "category": "Florencio Varela", - "y": 315432 - }, - { - "custom": { - "xLabel": "Amroha", - "yLabel": "137 061" - }, - "category": "Amroha", - "y": 137061 - }, - { - "custom": { - "xLabel": "El Limón", - "yLabel": "90 000" - }, - "category": "El Limón", - "y": 90000 - }, - { - "custom": { - "xLabel": "Thiruvananthapuram (Trivandrum", - "yLabel": "524 006" - }, - "category": "Thiruvananthapuram (Trivandrum", - "y": 524006 - }, - { - "custom": { - "xLabel": "Algeciras", - "yLabel": "103 106" - }, - "category": "Algeciras", - "y": 103106 - }, - { - "custom": { - "xLabel": "Dallas", - "yLabel": "1 188 580" - }, - "category": "Dallas", - "y": 1188580 - }, - { - "custom": { - "xLabel": "Port-of-Spain", - "yLabel": "43 396" - }, - "category": "Port-of-Spain", - "y": 43396 - }, - { - "custom": { - "xLabel": "Lowell", - "yLabel": "105 167" - }, - "category": "Lowell", - "y": 105167 - }, - { - "custom": { - "xLabel": "Uruguaiana", - "yLabel": "126 305" - }, - "category": "Uruguaiana", - "y": 126305 - }, - { - "custom": { - "xLabel": "Zhucheng", - "yLabel": "102 134" - }, - "category": "Zhucheng", - "y": 102134 - }, - { - "custom": { - "xLabel": "Little Rock", - "yLabel": "183 133" - }, - "category": "Little Rock", - "y": 183133 - }, - { - "custom": { - "xLabel": "Kananga", - "yLabel": "393 030" - }, - "category": "Kananga", - "y": 393030 - }, - { - "custom": { - "xLabel": "Votorantim", - "yLabel": "91 777" - }, - "category": "Votorantim", - "y": 91777 - }, - { - "custom": { - "xLabel": "Ichalkaranji", - "yLabel": "214 950" - }, - "category": "Ichalkaranji", - "y": 214950 - }, - { - "custom": { - "xLabel": "Lambaré", - "yLabel": "99 681" - }, - "category": "Lambaré", - "y": 99681 - }, - { - "custom": { - "xLabel": "Onomichi", - "yLabel": "93 756" - }, - "category": "Onomichi", - "y": 93756 - }, - { - "custom": { - "xLabel": "Ondo", - "yLabel": "173 600" - }, - "category": "Ondo", - "y": 173600 - }, - { - "custom": { - "xLabel": "Manzhouli", - "yLabel": "120 023" - }, - "category": "Manzhouli", - "y": 120023 - }, - { - "custom": { - "xLabel": "Chiba", - "yLabel": "863 930" - }, - "category": "Chiba", - "y": 863930 - }, - { - "custom": { - "xLabel": "Schaan", - "yLabel": "5 346" - }, - "category": "Schaan", - "y": 5346 - }, - { - "custom": { - "xLabel": "Handan", - "yLabel": "840 000" - }, - "category": "Handan", - "y": 840000 - }, - { - "custom": { - "xLabel": "Nanking [Nanjing]", - "yLabel": "2 870 300" - }, - "category": "Nanking [Nanjing]", - "y": 2870300 - }, - { - "custom": { - "xLabel": "Ueda", - "yLabel": "124 217" - }, - "category": "Ueda", - "y": 124217 - }, - { - "custom": { - "xLabel": "Centro (Villahermosa)", - "yLabel": "519 873" - }, - "category": "Centro (Villahermosa)", - "y": 519873 - }, - { - "custom": { - "xLabel": "Pireus", - "yLabel": "182 671" - }, - "category": "Pireus", - "y": 182671 - }, - { - "custom": { - "xLabel": "Tampico", - "yLabel": "294 789" - }, - "category": "Tampico", - "y": 294789 - }, - { - "custom": { - "xLabel": "Machilipatnam (Masulipatam)", - "yLabel": "159 110" - }, - "category": "Machilipatnam (Masulipatam)", - "y": 159110 - }, - { - "custom": { - "xLabel": "Lancaster", - "yLabel": "118 718" - }, - "category": "Lancaster", - "y": 118718 - }, - { - "custom": { - "xLabel": "Sungai Petani", - "yLabel": "114 763" - }, - "category": "Sungai Petani", - "y": 114763 - }, - { - "custom": { - "xLabel": "Sete Lagoas", - "yLabel": "182 984" - }, - "category": "Sete Lagoas", - "y": 182984 - }, - { - "custom": { - "xLabel": "Newport News", - "yLabel": "180 150" - }, - "category": "Newport News", - "y": 180150 - }, - { - "custom": { - "xLabel": "Xichang", - "yLabel": "134 419" - }, - "category": "Xichang", - "y": 134419 - }, - { - "custom": { - "xLabel": "Malita", - "yLabel": "100 000" - }, - "category": "Malita", - "y": 100000 - }, - { - "custom": { - "xLabel": "Concord", - "yLabel": "121 780" - }, - "category": "Concord", - "y": 121780 - }, - { - "custom": { - "xLabel": "Zamora", - "yLabel": "161 191" - }, - "category": "Zamora", - "y": 161191 - }, - { - "custom": { - "xLabel": "Candelaria", - "yLabel": "92 429" - }, - "category": "Candelaria", - "y": 92429 - }, - { - "custom": { - "xLabel": "Luoyang", - "yLabel": "760 000" - }, - "category": "Luoyang", - "y": 760000 - }, - { - "custom": { - "xLabel": "Teresópolis", - "yLabel": "128 079" - }, - "category": "Teresópolis", - "y": 128079 - }, - { - "custom": { - "xLabel": "Touliu", - "yLabel": "98 900" - }, - "category": "Touliu", - "y": 98900 - }, - { - "custom": { - "xLabel": "Worcester", - "yLabel": "95 000" - }, - "category": "Worcester", - "y": 95000 - }, - { - "custom": { - "xLabel": "Beaumont", - "yLabel": "113 866" - }, - "category": "Beaumont", - "y": 113866 - }, - { - "custom": { - "xLabel": "Reims", - "yLabel": "187 206" - }, - "category": "Reims", - "y": 187206 - }, - { - "custom": { - "xLabel": "Acámbaro", - "yLabel": "110 487" - }, - "category": "Acámbaro", - "y": 110487 - }, - { - "custom": { - "xLabel": "Ambala", - "yLabel": "122 596" - }, - "category": "Ambala", - "y": 122596 - }, - { - "custom": { - "xLabel": "Formosa", - "yLabel": "147 636" - }, - "category": "Formosa", - "y": 147636 - }, - { - "custom": { - "xLabel": "Quezon", - "yLabel": "2 173 831" - }, - "category": "Quezon", - "y": 2173831 - }, - { - "custom": { - "xLabel": "Barra do Piraí", - "yLabel": "89 388" - }, - "category": "Barra do Piraí", - "y": 89388 - }, - { - "custom": { - "xLabel": "al-Hufuf", - "yLabel": "225 800" - }, - "category": "al-Hufuf", - "y": 225800 - }, - { - "custom": { - "xLabel": "Brahmanbaria", - "yLabel": "109 032" - }, - "category": "Brahmanbaria", - "y": 109032 - }, - { - "custom": { - "xLabel": "Tambov", - "yLabel": "312 000" - }, - "category": "Tambov", - "y": 312000 - }, - { - "custom": { - "xLabel": "Lower Hutt", - "yLabel": "98 100" - }, - "category": "Lower Hutt", - "y": 98100 - }, - { - "custom": { - "xLabel": "Damoh", - "yLabel": "95 661" - }, - "category": "Damoh", - "y": 95661 - }, - { - "custom": { - "xLabel": "Wroclaw", - "yLabel": "636 765" - }, - "category": "Wroclaw", - "y": 636765 - }, - { - "custom": { - "xLabel": "Denpasar", - "yLabel": "435 000" - }, - "category": "Denpasar", - "y": 435000 - }, - { - "custom": { - "xLabel": "Limeira", - "yLabel": "245 497" - }, - "category": "Limeira", - "y": 245497 - }, - { - "custom": { - "xLabel": "Kielce", - "yLabel": "212 383" - }, - "category": "Kielce", - "y": 212383 - }, - { - "custom": { - "xLabel": "Santa Ana", - "yLabel": "139 389" - }, - "category": "Santa Ana", - "y": 139389 - }, - { - "custom": { - "xLabel": "Strasbourg", - "yLabel": "264 115" - }, - "category": "Strasbourg", - "y": 264115 - }, - { - "custom": { - "xLabel": "Muzaffarpur", - "yLabel": "241 107" - }, - "category": "Muzaffarpur", - "y": 241107 - }, - { - "custom": { - "xLabel": "Belize City", - "yLabel": "55 810" - }, - "category": "Belize City", - "y": 55810 - }, - { - "custom": { - "xLabel": "Modesto", - "yLabel": "188 856" - }, - "category": "Modesto", - "y": 188856 - }, - { - "custom": { - "xLabel": "Moratuwa", - "yLabel": "190 000" - }, - "category": "Moratuwa", - "y": 190000 - }, - { - "custom": { - "xLabel": "Vientiane", - "yLabel": "531 800" - }, - "category": "Vientiane", - "y": 531800 - }, - { - "custom": { - "xLabel": "Warszawa", - "yLabel": "1 615 369" - }, - "category": "Warszawa", - "y": 1615369 - }, - { - "custom": { - "xLabel": "Malolos", - "yLabel": "175 291" - }, - "category": "Malolos", - "y": 175291 - }, - { - "custom": { - "xLabel": "Wanxian", - "yLabel": "156 823" - }, - "category": "Wanxian", - "y": 156823 - }, - { - "custom": { - "xLabel": "Vinnytsja", - "yLabel": "391 000" - }, - "category": "Vinnytsja", - "y": 391000 - }, - { - "custom": { - "xLabel": "Bayamo", - "yLabel": "141 000" - }, - "category": "Bayamo", - "y": 141000 - }, - { - "custom": { - "xLabel": "Aalborg", - "yLabel": "161 161" - }, - "category": "Aalborg", - "y": 161161 - }, - { - "custom": { - "xLabel": "Osasco", - "yLabel": "659 604" - }, - "category": "Osasco", - "y": 659604 - }, - { - "custom": { - "xLabel": "Mezduretšensk", - "yLabel": "104 400" - }, - "category": "Mezduretšensk", - "y": 104400 - }, - { - "custom": { - "xLabel": "Igboho", - "yLabel": "106 800" - }, - "category": "Igboho", - "y": 106800 - }, - { - "custom": { - "xLabel": "Iwatsuki", - "yLabel": "110 034" - }, - "category": "Iwatsuki", - "y": 110034 - }, - { - "custom": { - "xLabel": "Temapache", - "yLabel": "102 824" - }, - "category": "Temapache", - "y": 102824 - }, - { - "custom": { - "xLabel": "Roma", - "yLabel": "2 643 581" - }, - "category": "Roma", - "y": 2643581 - }, - { - "custom": { - "xLabel": "Kingston upon Hull", - "yLabel": "262 000" - }, - "category": "Kingston upon Hull", - "y": 262000 - }, - { - "custom": { - "xLabel": "Emmen", - "yLabel": "105 853" - }, - "category": "Emmen", - "y": 105853 - }, - { - "custom": { - "xLabel": "Bhusawal", - "yLabel": "145 143" - }, - "category": "Bhusawal", - "y": 145143 - }, - { - "custom": { - "xLabel": "Hugli-Chinsurah", - "yLabel": "151 806" - }, - "category": "Hugli-Chinsurah", - "y": 151806 - }, - { - "custom": { - "xLabel": "Khoy", - "yLabel": "148 944" - }, - "category": "Khoy", - "y": 148944 - }, - { - "custom": { - "xLabel": "Bayamón", - "yLabel": "224 044" - }, - "category": "Bayamón", - "y": 224044 - }, - { - "custom": { - "xLabel": "Mabalacat", - "yLabel": "171 045" - }, - "category": "Mabalacat", - "y": 171045 - }, - { - "custom": { - "xLabel": "Khorramabad", - "yLabel": "272 815" - }, - "category": "Khorramabad", - "y": 272815 - }, - { - "custom": { - "xLabel": "Zaragoza", - "yLabel": "603 367" - }, - "category": "Zaragoza", - "y": 603367 - }, - { - "custom": { - "xLabel": "Alofi", - "yLabel": "682" - }, - "category": "Alofi", - "y": 682 - }, - { - "custom": { - "xLabel": "Pittsburgh", - "yLabel": "334 563" - }, - "category": "Pittsburgh", - "y": 334563 - }, - { - "custom": { - "xLabel": "Ituzaingó", - "yLabel": "158 197" - }, - "category": "Ituzaingó", - "y": 158197 - }, - { - "custom": { - "xLabel": "Beihai", - "yLabel": "112 673" - }, - "category": "Beihai", - "y": 112673 - }, - { - "custom": { - "xLabel": "Bengbu", - "yLabel": "449 245" - }, - "category": "Bengbu", - "y": 449245 - }, - { - "custom": { - "xLabel": "Potchefstroom", - "yLabel": "101 817" - }, - "category": "Potchefstroom", - "y": 101817 - }, - { - "custom": { - "xLabel": "Columbus", - "yLabel": "186 291" - }, - "category": "Columbus", - "y": 186291 - }, - { - "custom": { - "xLabel": "Wolfsburg", - "yLabel": "121 954" - }, - "category": "Wolfsburg", - "y": 121954 - }, - { - "custom": { - "xLabel": "Damascus", - "yLabel": "1 347 000" - }, - "category": "Damascus", - "y": 1347000 - }, - { - "custom": { - "xLabel": "Nizni Tagil", - "yLabel": "390 900" - }, - "category": "Nizni Tagil", - "y": 390900 - }, - { - "custom": { - "xLabel": "Darmstadt", - "yLabel": "137 776" - }, - "category": "Darmstadt", - "y": 137776 - }, - { - "custom": { - "xLabel": "Bantam", - "yLabel": "503" - }, - "category": "Bantam", - "y": 503 - }, - { - "custom": { - "xLabel": "La Serena", - "yLabel": "137 409" - }, - "category": "La Serena", - "y": 137409 - }, - { - "custom": { - "xLabel": "Nyeri", - "yLabel": "91 258" - }, - "category": "Nyeri", - "y": 91258 - }, - { - "custom": { - "xLabel": "Cape Town", - "yLabel": "2 352 121" - }, - "category": "Cape Town", - "y": 2352121 - }, - { - "custom": { - "xLabel": "Pondokgede", - "yLabel": "263 200" - }, - "category": "Pondokgede", - "y": 263200 - }, - { - "custom": { - "xLabel": "Hiratsuka", - "yLabel": "254 207" - }, - "category": "Hiratsuka", - "y": 254207 - }, - { - "custom": { - "xLabel": "Richmond", - "yLabel": "148 867" - }, - "category": "Richmond", - "y": 148867 - }, - { - "custom": { - "xLabel": "Fukuyama", - "yLabel": "376 921" - }, - "category": "Fukuyama", - "y": 376921 - }, - { - "custom": { - "xLabel": "Bristol", - "yLabel": "402 000" - }, - "category": "Bristol", - "y": 402000 - }, - { - "custom": { - "xLabel": "Araguaína", - "yLabel": "114 948" - }, - "category": "Araguaína", - "y": 114948 - }, - { - "custom": { - "xLabel": "Tangshan", - "yLabel": "1 040 000" - }, - "category": "Tangshan", - "y": 1040000 - }, - { - "custom": { - "xLabel": "Bogra", - "yLabel": "120 170" - }, - "category": "Bogra", - "y": 120170 - }, - { - "custom": { - "xLabel": "León", - "yLabel": "139 809" - }, - "category": "León", - "y": 139809 - }, - { - "custom": { - "xLabel": "Amiens", - "yLabel": "135 501" - }, - "category": "Amiens", - "y": 135501 - }, - { - "custom": { - "xLabel": "Buenaventura", - "yLabel": "224 336" - }, - "category": "Buenaventura", - "y": 224336 - }, - { - "custom": { - "xLabel": "Yiyang", - "yLabel": "185 818" - }, - "category": "Yiyang", - "y": 185818 - }, - { - "custom": { - "xLabel": "Chonan", - "yLabel": "330 259" - }, - "category": "Chonan", - "y": 330259 - }, - { - "custom": { - "xLabel": "Epe", - "yLabel": "101 000" - }, - "category": "Epe", - "y": 101000 - }, - { - "custom": { - "xLabel": "Apeldoorn", - "yLabel": "153 491" - }, - "category": "Apeldoorn", - "y": 153491 - }, - { - "custom": { - "xLabel": "Tlaquepaque", - "yLabel": "475 472" - }, - "category": "Tlaquepaque", - "y": 475472 - }, - { - "custom": { - "xLabel": "Itaituba", - "yLabel": "101 320" - }, - "category": "Itaituba", - "y": 101320 - }, - { - "custom": { - "xLabel": "Lecce", - "yLabel": "98 208" - }, - "category": "Lecce", - "y": 98208 - }, - { - "custom": { - "xLabel": "Phan Thiêt", - "yLabel": "114 236" - }, - "category": "Phan Thiêt", - "y": 114236 - }, - { - "custom": { - "xLabel": "Nishinomiya", - "yLabel": "397 618" - }, - "category": "Nishinomiya", - "y": 397618 - }, - { - "custom": { - "xLabel": "Calamba", - "yLabel": "281 146" - }, - "category": "Calamba", - "y": 281146 - }, - { - "custom": { - "xLabel": "Coronel Fabriciano", - "yLabel": "95 933" - }, - "category": "Coronel Fabriciano", - "y": 95933 - }, - { - "custom": { - "xLabel": "Zwolle", - "yLabel": "105 819" - }, - "category": "Zwolle", - "y": 105819 - }, - { - "custom": { - "xLabel": "Oral", - "yLabel": "195 500" - }, - "category": "Oral", - "y": 195500 - }, - { - "custom": { - "xLabel": "Oujda", - "yLabel": "365 382" - }, - "category": "Oujda", - "y": 365382 - }, - { - "custom": { - "xLabel": "Shantou", - "yLabel": "580 000" - }, - "category": "Shantou", - "y": 580000 - }, - { - "custom": { - "xLabel": "Vologda", - "yLabel": "302 500" - }, - "category": "Vologda", - "y": 302500 - }, - { - "custom": { - "xLabel": "Székesfehérvár", - "yLabel": "105 119" - }, - "category": "Székesfehérvár", - "y": 105119 - }, - { - "custom": { - "xLabel": "Tsaotun", - "yLabel": "96 800" - }, - "category": "Tsaotun", - "y": 96800 - }, - { - "custom": { - "xLabel": "Vicente López", - "yLabel": "288 341" - }, - "category": "Vicente López", - "y": 288341 - }, - { - "custom": { - "xLabel": "Akure", - "yLabel": "162 300" - }, - "category": "Akure", - "y": 162300 - }, - { - "custom": { - "xLabel": "Münster", - "yLabel": "264 670" - }, - "category": "Münster", - "y": 264670 - }, - { - "custom": { - "xLabel": "Tiruvannamalai", - "yLabel": "109 196" - }, - "category": "Tiruvannamalai", - "y": 109196 - }, - { - "custom": { - "xLabel": "Grudziadz", - "yLabel": "102 434" - }, - "category": "Grudziadz", - "y": 102434 - }, - { - "custom": { - "xLabel": "Guangshui", - "yLabel": "102 770" - }, - "category": "Guangshui", - "y": 102770 - }, - { - "custom": { - "xLabel": "Kakamigahara", - "yLabel": "131 831" - }, - "category": "Kakamigahara", - "y": 131831 - }, - { - "custom": { - "xLabel": "Tomakomai", - "yLabel": "171 958" - }, - "category": "Tomakomai", - "y": 171958 - }, - { - "custom": { - "xLabel": "Schwerin", - "yLabel": "102 878" - }, - "category": "Schwerin", - "y": 102878 - }, - { - "custom": { - "xLabel": "Dili", - "yLabel": "47 900" - }, - "category": "Dili", - "y": 47900 - }, - { - "custom": { - "xLabel": "Öskemen", - "yLabel": "311 000" - }, - "category": "Öskemen", - "y": 311000 - }, - { - "custom": { - "xLabel": "Taranto", - "yLabel": "208 214" - }, - "category": "Taranto", - "y": 208214 - }, - { - "custom": { - "xLabel": "Barahanagar (Baranagar)", - "yLabel": "224 821" - }, - "category": "Barahanagar (Baranagar)", - "y": 224821 - }, - { - "custom": { - "xLabel": "La Matanza", - "yLabel": "1 266 461" - }, - "category": "La Matanza", - "y": 1266461 - }, - { - "custom": { - "xLabel": "Basildon", - "yLabel": "100 924" - }, - "category": "Basildon", - "y": 100924 - }, - { - "custom": { - "xLabel": "Araras", - "yLabel": "101 046" - }, - "category": "Araras", - "y": 101046 - }, - { - "custom": { - "xLabel": "Xuzhou", - "yLabel": "810 000" - }, - "category": "Xuzhou", - "y": 810000 - }, - { - "custom": { - "xLabel": "Hidalgo del Parral", - "yLabel": "100 881" - }, - "category": "Hidalgo del Parral", - "y": 100881 - }, - { - "custom": { - "xLabel": "Andong", - "yLabel": "188 443" - }, - "category": "Andong", - "y": 188443 - }, - { - "custom": { - "xLabel": "Diadema", - "yLabel": "335 078" - }, - "category": "Diadema", - "y": 335078 - }, - { - "custom": { - "xLabel": "Shiyan", - "yLabel": "273 786" - }, - "category": "Shiyan", - "y": 273786 - }, - { - "custom": { - "xLabel": "Durg", - "yLabel": "150 645" - }, - "category": "Durg", - "y": 150645 - }, - { - "custom": { - "xLabel": "Helsingborg", - "yLabel": "117 737" - }, - "category": "Helsingborg", - "y": 117737 - }, - { - "custom": { - "xLabel": "Pinar del Río", - "yLabel": "142 100" - }, - "category": "Pinar del Río", - "y": 142100 - }, - { - "custom": { - "xLabel": "Maragheh", - "yLabel": "132 318" - }, - "category": "Maragheh", - "y": 132318 - }, - { - "custom": { - "xLabel": "Bridgeport", - "yLabel": "139 529" - }, - "category": "Bridgeport", - "y": 139529 - }, - { - "custom": { - "xLabel": "Sukkur", - "yLabel": "329 176" - }, - "category": "Sukkur", - "y": 329176 - }, - { - "custom": { - "xLabel": "Zaporizzja", - "yLabel": "848 000" - }, - "category": "Zaporizzja", - "y": 848000 - }, - { - "custom": { - "xLabel": "Shihung", - "yLabel": "133 443" - }, - "category": "Shihung", - "y": 133443 - }, - { - "custom": { - "xLabel": "Bokaro Steel City", - "yLabel": "333 683" - }, - "category": "Bokaro Steel City", - "y": 333683 - }, - { - "custom": { - "xLabel": "Suita", - "yLabel": "345 750" - }, - "category": "Suita", - "y": 345750 - }, - { - "custom": { - "xLabel": "Bari", - "yLabel": "331 848" - }, - "category": "Bari", - "y": 331848 - }, - { - "custom": { - "xLabel": "Teixeira de Freitas", - "yLabel": "108 441" - }, - "category": "Teixeira de Freitas", - "y": 108441 - }, - { - "custom": { - "xLabel": "Kimchaek", - "yLabel": "179 000" - }, - "category": "Kimchaek", - "y": 179000 - }, - { - "custom": { - "xLabel": "Tallahassee", - "yLabel": "150 624" - }, - "category": "Tallahassee", - "y": 150624 - }, - { - "custom": { - "xLabel": "Tanta", - "yLabel": "371 010" - }, - "category": "Tanta", - "y": 371010 - }, - { - "custom": { - "xLabel": "Oshogbo", - "yLabel": "476 800" - }, - "category": "Oshogbo", - "y": 476800 - }, - { - "custom": { - "xLabel": "Sanming", - "yLabel": "160 691" - }, - "category": "Sanming", - "y": 160691 - }, - { - "custom": { - "xLabel": "Mülheim an der Ruhr", - "yLabel": "173 895" - }, - "category": "Mülheim an der Ruhr", - "y": 173895 - }, - { - "custom": { - "xLabel": "Pueblo", - "yLabel": "102 121" - }, - "category": "Pueblo", - "y": 102121 - }, - { - "custom": { - "xLabel": "Ibagué", - "yLabel": "393 664" - }, - "category": "Ibagué", - "y": 393664 - }, - { - "custom": { - "xLabel": "Heidelberg", - "yLabel": "139 672" - }, - "category": "Heidelberg", - "y": 139672 - }, - { - "custom": { - "xLabel": "Sanya", - "yLabel": "102 820" - }, - "category": "Sanya", - "y": 102820 - }, - { - "custom": { - "xLabel": "Ayacucho", - "yLabel": "118 960" - }, - "category": "Ayacucho", - "y": 118960 - }, - { - "custom": { - "xLabel": "Tiruvottiyur", - "yLabel": "172 562" - }, - "category": "Tiruvottiyur", - "y": 172562 - }, - { - "custom": { - "xLabel": "Lida", - "yLabel": "101 000" - }, - "category": "Lida", - "y": 101000 - }, - { - "custom": { - "xLabel": "Erlangen", - "yLabel": "100 750" - }, - "category": "Erlangen", - "y": 100750 - }, - { - "custom": { - "xLabel": "Papeete", - "yLabel": "25 553" - }, - "category": "Papeete", - "y": 25553 - }, - { - "custom": { - "xLabel": "Kinešma", - "yLabel": "100 000" - }, - "category": "Kinešma", - "y": 100000 - }, - { - "custom": { - "xLabel": "Kirovo-Tšepetsk", - "yLabel": "91 600" - }, - "category": "Kirovo-Tšepetsk", - "y": 91600 - }, - { - "custom": { - "xLabel": "Arnhem", - "yLabel": "138 020" - }, - "category": "Arnhem", - "y": 138020 - }, - { - "custom": { - "xLabel": "Lipa", - "yLabel": "218 447" - }, - "category": "Lipa", - "y": 218447 - }, - { - "custom": { - "xLabel": "Mitšurinsk", - "yLabel": "120 700" - }, - "category": "Mitšurinsk", - "y": 120700 - }, - { - "custom": { - "xLabel": "Hurlingham", - "yLabel": "170 028" - }, - "category": "Hurlingham", - "y": 170028 - }, - { - "custom": { - "xLabel": "Laredo", - "yLabel": "176 576" - }, - "category": "Laredo", - "y": 176576 - }, - { - "custom": { - "xLabel": "Tulancingo de Bravo", - "yLabel": "121 946" - }, - "category": "Tulancingo de Bravo", - "y": 121946 - }, - { - "custom": { - "xLabel": "Bojnurd", - "yLabel": "134 835" - }, - "category": "Bojnurd", - "y": 134835 - }, - { - "custom": { - "xLabel": "Krishnanagar", - "yLabel": "121 110" - }, - "category": "Krishnanagar", - "y": 121110 - }, - { - "custom": { - "xLabel": "Jaroslavl", - "yLabel": "616 700" - }, - "category": "Jaroslavl", - "y": 616700 - }, - { - "custom": { - "xLabel": "Binzhou", - "yLabel": "133 555" - }, - "category": "Binzhou", - "y": 133555 - }, - { - "custom": { - "xLabel": "Birjand", - "yLabel": "127 608" - }, - "category": "Birjand", - "y": 127608 - }, - { - "custom": { - "xLabel": "Bobruisk", - "yLabel": "221 000" - }, - "category": "Bobruisk", - "y": 221000 - }, - { - "custom": { - "xLabel": "Boise City", - "yLabel": "185 787" - }, - "category": "Boise City", - "y": 185787 - }, - { - "custom": { - "xLabel": "Iasi", - "yLabel": "348 070" - }, - "category": "Iasi", - "y": 348070 - }, - { - "custom": { - "xLabel": "Stoke-on-Trent", - "yLabel": "252 000" - }, - "category": "Stoke-on-Trent", - "y": 252000 - }, - { - "custom": { - "xLabel": "Yokkaichi", - "yLabel": "288 173" - }, - "category": "Yokkaichi", - "y": 288173 - }, - { - "custom": { - "xLabel": "Richmond", - "yLabel": "94 100" - }, - "category": "Richmond", - "y": 94100 - }, - { - "custom": { - "xLabel": "Spokane", - "yLabel": "195 629" - }, - "category": "Spokane", - "y": 195629 - }, - { - "custom": { - "xLabel": "Sakai", - "yLabel": "797 735" - }, - "category": "Sakai", - "y": 797735 - }, - { - "custom": { - "xLabel": "Ciomas", - "yLabel": "187 400" - }, - "category": "Ciomas", - "y": 187400 - }, - { - "custom": { - "xLabel": "Curicó", - "yLabel": "115 766" - }, - "category": "Curicó", - "y": 115766 - }, - { - "custom": { - "xLabel": "Erfurt", - "yLabel": "201 267" - }, - "category": "Erfurt", - "y": 201267 - }, - { - "custom": { - "xLabel": "Multan", - "yLabel": "1 182 441" - }, - "category": "Multan", - "y": 1182441 - }, - { - "custom": { - "xLabel": "Kasuga", - "yLabel": "101 344" - }, - "category": "Kasuga", - "y": 101344 - }, - { - "custom": { - "xLabel": "Peristerion", - "yLabel": "137 288" - }, - "category": "Peristerion", - "y": 137288 - }, - { - "custom": { - "xLabel": "Mitaka", - "yLabel": "167 268" - }, - "category": "Mitaka", - "y": 167268 - }, - { - "custom": { - "xLabel": "Novyi Urengoi", - "yLabel": "89 800" - }, - "category": "Novyi Urengoi", - "y": 89800 - }, - { - "custom": { - "xLabel": "Neftejugansk", - "yLabel": "97 400" - }, - "category": "Neftejugansk", - "y": 97400 - }, - { - "custom": { - "xLabel": "Jenakijeve", - "yLabel": "105 000" - }, - "category": "Jenakijeve", - "y": 105000 - }, - { - "custom": { - "xLabel": "Groningen", - "yLabel": "172 701" - }, - "category": "Groningen", - "y": 172701 - }, - { - "custom": { - "xLabel": "Ica", - "yLabel": "194 820" - }, - "category": "Ica", - "y": 194820 - }, - { - "custom": { - "xLabel": "Jombang", - "yLabel": "92 600" - }, - "category": "Jombang", - "y": 92600 - }, - { - "custom": { - "xLabel": "Botucatu", - "yLabel": "107 663" - }, - "category": "Botucatu", - "y": 107663 - }, - { - "custom": { - "xLabel": "Macao", - "yLabel": "437 500" - }, - "category": "Macao", - "y": 437500 - }, - { - "custom": { - "xLabel": "Panipat", - "yLabel": "215 218" - }, - "category": "Panipat", - "y": 215218 - }, - { - "custom": { - "xLabel": "Gomel", - "yLabel": "475 000" - }, - "category": "Gomel", - "y": 475000 - }, - { - "custom": { - "xLabel": "Sunchon", - "yLabel": "249 263" - }, - "category": "Sunchon", - "y": 249263 - }, - { - "custom": { - "xLabel": "Ribeirão Pires", - "yLabel": "108 121" - }, - "category": "Ribeirão Pires", - "y": 108121 - }, - { - "custom": { - "xLabel": "Beipiao", - "yLabel": "194 301" - }, - "category": "Beipiao", - "y": 194301 - }, - { - "custom": { - "xLabel": "al-Fashir", - "yLabel": "141 884" - }, - "category": "al-Fashir", - "y": 141884 - }, - { - "custom": { - "xLabel": "Tirupati", - "yLabel": "174 369" - }, - "category": "Tirupati", - "y": 174369 - }, - { - "custom": { - "xLabel": "Udon Thani", - "yLabel": "158 100" - }, - "category": "Udon Thani", - "y": 158100 - }, - { - "custom": { - "xLabel": "Halifax", - "yLabel": "91 069" - }, - "category": "Halifax", - "y": 91069 - }, - { - "custom": { - "xLabel": "Newcastle upon Tyne", - "yLabel": "189 150" - }, - "category": "Newcastle upon Tyne", - "y": 189150 - }, - { - "custom": { - "xLabel": "Douglas", - "yLabel": "23 487" - }, - "category": "Douglas", - "y": 23487 - }, - { - "custom": { - "xLabel": "Les Abymes", - "yLabel": "62 947" - }, - "category": "Les Abymes", - "y": 62947 - }, - { - "custom": { - "xLabel": "San Francisco de Macorís", - "yLabel": "108 485" - }, - "category": "San Francisco de Macorís", - "y": 108485 - }, - { - "custom": { - "xLabel": "Jerez de la Frontera", - "yLabel": "182 660" - }, - "category": "Jerez de la Frontera", - "y": 182660 - }, - { - "custom": { - "xLabel": "Stavropol", - "yLabel": "343 300" - }, - "category": "Stavropol", - "y": 343300 - }, - { - "custom": { - "xLabel": "Olmalik", - "yLabel": "114 900" - }, - "category": "Olmalik", - "y": 114900 - }, - { - "custom": { - "xLabel": "Valledupar", - "yLabel": "263 247" - }, - "category": "Valledupar", - "y": 263247 - }, - { - "custom": { - "xLabel": "al-Salimiya", - "yLabel": "130 215" - }, - "category": "al-Salimiya", - "y": 130215 - }, - { - "custom": { - "xLabel": "Uzgorod", - "yLabel": "127 000" - }, - "category": "Uzgorod", - "y": 127000 - }, - { - "custom": { - "xLabel": "Bharatpur", - "yLabel": "148 519" - }, - "category": "Bharatpur", - "y": 148519 - }, - { - "custom": { - "xLabel": "Southend-on-Sea", - "yLabel": "176 000" - }, - "category": "Southend-on-Sea", - "y": 176000 - }, - { - "custom": { - "xLabel": "Acarigua", - "yLabel": "158 954" - }, - "category": "Acarigua", - "y": 158954 - }, - { - "custom": { - "xLabel": "Qingyuan", - "yLabel": "164 641" - }, - "category": "Qingyuan", - "y": 164641 - }, - { - "custom": { - "xLabel": "Hapur", - "yLabel": "146 262" - }, - "category": "Hapur", - "y": 146262 - }, - { - "custom": { - "xLabel": "Dimitrovgrad", - "yLabel": "137 000" - }, - "category": "Dimitrovgrad", - "y": 137000 - }, - { - "custom": { - "xLabel": "Sonipat (Sonepat)", - "yLabel": "143 922" - }, - "category": "Sonipat (Sonepat)", - "y": 143922 - }, - { - "custom": { - "xLabel": "Palmas", - "yLabel": "121 919" - }, - "category": "Palmas", - "y": 121919 - }, - { - "custom": { - "xLabel": "Kamjanets-Podilskyi", - "yLabel": "109 000" - }, - "category": "Kamjanets-Podilskyi", - "y": 109000 - }, - { - "custom": { - "xLabel": "Århus", - "yLabel": "284 846" - }, - "category": "Århus", - "y": 284846 - }, - { - "custom": { - "xLabel": "Los Cabos", - "yLabel": "105 199" - }, - "category": "Los Cabos", - "y": 105199 - }, - { - "custom": { - "xLabel": "Chärjew", - "yLabel": "189 200" - }, - "category": "Chärjew", - "y": 189200 - }, - { - "custom": { - "xLabel": "Sacramento", - "yLabel": "407 018" - }, - "category": "Sacramento", - "y": 407018 - }, - { - "custom": { - "xLabel": "Puqi", - "yLabel": "117 264" - }, - "category": "Puqi", - "y": 117264 - }, - { - "custom": { - "xLabel": "Ciudad Guayana", - "yLabel": "663 713" - }, - "category": "Ciudad Guayana", - "y": 663713 - }, - { - "custom": { - "xLabel": "Grodno", - "yLabel": "302 000" - }, - "category": "Grodno", - "y": 302000 - }, - { - "custom": { - "xLabel": "Camaçari", - "yLabel": "149 146" - }, - "category": "Camaçari", - "y": 149146 - }, - { - "custom": { - "xLabel": "Zeleznodoroznyi", - "yLabel": "100 100" - }, - "category": "Zeleznodoroznyi", - "y": 100100 - }, - { - "custom": { - "xLabel": "Liaoyuan", - "yLabel": "354 141" - }, - "category": "Liaoyuan", - "y": 354141 - }, - { - "custom": { - "xLabel": "Ndola", - "yLabel": "329 200" - }, - "category": "Ndola", - "y": 329200 - }, - { - "custom": { - "xLabel": "Apia", - "yLabel": "35 900" - }, - "category": "Apia", - "y": 35900 - }, - { - "custom": { - "xLabel": "Pasuruan", - "yLabel": "134 019" - }, - "category": "Pasuruan", - "y": 134019 - }, - { - "custom": { - "xLabel": "Passo Fundo", - "yLabel": "166 343" - }, - "category": "Passo Fundo", - "y": 166343 - }, - { - "custom": { - "xLabel": "Fullerton", - "yLabel": "126 003" - }, - "category": "Fullerton", - "y": 126003 - }, - { - "custom": { - "xLabel": "Ciputat", - "yLabel": "270 800" - }, - "category": "Ciputat", - "y": 270800 - }, - { - "custom": { - "xLabel": "Braila", - "yLabel": "233 756" - }, - "category": "Braila", - "y": 233756 - }, - { - "custom": { - "xLabel": "Ponta Grossa", - "yLabel": "268 013" - }, - "category": "Ponta Grossa", - "y": 268013 - }, - { - "custom": { - "xLabel": "Toyota", - "yLabel": "346 090" - }, - "category": "Toyota", - "y": 346090 - }, - { - "custom": { - "xLabel": "Suzano", - "yLabel": "195 434" - }, - "category": "Suzano", - "y": 195434 - }, - { - "custom": { - "xLabel": "Paradise", - "yLabel": "124 682" - }, - "category": "Paradise", - "y": 124682 - }, - { - "custom": { - "xLabel": "Harare", - "yLabel": "1 410 000" - }, - "category": "Harare", - "y": 1410000 - }, - { - "custom": { - "xLabel": "Valera", - "yLabel": "130 281" - }, - "category": "Valera", - "y": 130281 - }, - { - "custom": { - "xLabel": "Bhilwara", - "yLabel": "183 965" - }, - "category": "Bhilwara", - "y": 183965 - }, - { - "custom": { - "xLabel": "Gorzów Wielkopolski", - "yLabel": "126 019" - }, - "category": "Gorzów Wielkopolski", - "y": 126019 - }, - { - "custom": { - "xLabel": "Inisa", - "yLabel": "119 800" - }, - "category": "Inisa", - "y": 119800 - }, - { - "custom": { - "xLabel": "Satna", - "yLabel": "156 630" - }, - "category": "Satna", - "y": 156630 - }, - { - "custom": { - "xLabel": "Ede", - "yLabel": "307 100" - }, - "category": "Ede", - "y": 307100 - }, - { - "custom": { - "xLabel": "Bacolod", - "yLabel": "429 076" - }, - "category": "Bacolod", - "y": 429076 - }, - { - "custom": { - "xLabel": "Szczecin", - "yLabel": "416 988" - }, - "category": "Szczecin", - "y": 416988 - }, - { - "custom": { - "xLabel": "Malaybalay", - "yLabel": "123 672" - }, - "category": "Malaybalay", - "y": 123672 - }, - { - "custom": { - "xLabel": "Guaynabo", - "yLabel": "100 053" - }, - "category": "Guaynabo", - "y": 100053 - }, - { - "custom": { - "xLabel": "Inegöl", - "yLabel": "90 500" - }, - "category": "Inegöl", - "y": 90500 - }, - { - "custom": { - "xLabel": "Inchon", - "yLabel": "2 559 424" - }, - "category": "Inchon", - "y": 2559424 - }, - { - "custom": { - "xLabel": "Qitaihe", - "yLabel": "214 957" - }, - "category": "Qitaihe", - "y": 214957 - }, - { - "custom": { - "xLabel": "Batumi", - "yLabel": "137 700" - }, - "category": "Batumi", - "y": 137700 - }, - { - "custom": { - "xLabel": "Mérida", - "yLabel": "224 887" - }, - "category": "Mérida", - "y": 224887 - }, - { - "custom": { - "xLabel": "Novorossijsk", - "yLabel": "203 300" - }, - "category": "Novorossijsk", - "y": 203300 - }, - { - "custom": { - "xLabel": "Augsburg", - "yLabel": "254 867" - }, - "category": "Augsburg", - "y": 254867 - }, - { - "custom": { - "xLabel": "Charlotte", - "yLabel": "540 828" - }, - "category": "Charlotte", - "y": 540828 - }, - { - "custom": { - "xLabel": "Oxford", - "yLabel": "144 000" - }, - "category": "Oxford", - "y": 144000 - }, - { - "custom": { - "xLabel": "Kingston", - "yLabel": "103 962" - }, - "category": "Kingston", - "y": 103962 - }, - { - "custom": { - "xLabel": "Okayama", - "yLabel": "624 269" - }, - "category": "Okayama", - "y": 624269 - }, - { - "custom": { - "xLabel": "Madrid", - "yLabel": "2 879 052" - }, - "category": "Madrid", - "y": 2879052 - }, - { - "custom": { - "xLabel": "Pretoria", - "yLabel": "658 630" - }, - "category": "Pretoria", - "y": 658630 - }, - { - "custom": { - "xLabel": "Oslo", - "yLabel": "508 726" - }, - "category": "Oslo", - "y": 508726 - }, - { - "custom": { - "xLabel": "Pervouralsk", - "yLabel": "136 100" - }, - "category": "Pervouralsk", - "y": 136100 - }, - { - "custom": { - "xLabel": "Hargeysa", - "yLabel": "90 000" - }, - "category": "Hargeysa", - "y": 90000 - }, - { - "custom": { - "xLabel": "Yogyakarta", - "yLabel": "418 944" - }, - "category": "Yogyakarta", - "y": 418944 - }, - { - "custom": { - "xLabel": "Qianjiang", - "yLabel": "205 504" - }, - "category": "Qianjiang", - "y": 205504 - }, - { - "custom": { - "xLabel": "Barranquilla", - "yLabel": "1 223 260" - }, - "category": "Barranquilla", - "y": 1223260 - }, - { - "custom": { - "xLabel": "Sawangan", - "yLabel": "91 100" - }, - "category": "Sawangan", - "y": 91100 - }, - { - "custom": { - "xLabel": "Peshawar", - "yLabel": "988 005" - }, - "category": "Peshawar", - "y": 988005 - }, - { - "custom": { - "xLabel": "Wardha", - "yLabel": "102 985" - }, - "category": "Wardha", - "y": 102985 - }, - { - "custom": { - "xLabel": "Asan", - "yLabel": "154 663" - }, - "category": "Asan", - "y": 154663 - }, - { - "custom": { - "xLabel": "Fremont", - "yLabel": "203 413" - }, - "category": "Fremont", - "y": 203413 - }, - { - "custom": { - "xLabel": "Tuluá", - "yLabel": "152 488" - }, - "category": "Tuluá", - "y": 152488 - }, - { - "custom": { - "xLabel": "Burlington", - "yLabel": "145 150" - }, - "category": "Burlington", - "y": 145150 - }, - { - "custom": { - "xLabel": "Irbil", - "yLabel": "485 968" - }, - "category": "Irbil", - "y": 485968 - }, - { - "custom": { - "xLabel": "Lafia", - "yLabel": "122 500" - }, - "category": "Lafia", - "y": 122500 - }, - { - "custom": { - "xLabel": "Jaú", - "yLabel": "109 965" - }, - "category": "Jaú", - "y": 109965 - }, - { - "custom": { - "xLabel": "Nabereznyje Tšelny", - "yLabel": "514 700" - }, - "category": "Nabereznyje Tšelny", - "y": 514700 - }, - { - "custom": { - "xLabel": "Praha", - "yLabel": "1 181 126" - }, - "category": "Praha", - "y": 1181126 - }, - { - "custom": { - "xLabel": "Pasay", - "yLabel": "354 908" - }, - "category": "Pasay", - "y": 354908 - }, - { - "custom": { - "xLabel": "Fuyang", - "yLabel": "179 572" - }, - "category": "Fuyang", - "y": 179572 - }, - { - "custom": { - "xLabel": "São José", - "yLabel": "155 105" - }, - "category": "São José", - "y": 155105 - }, - { - "custom": { - "xLabel": "Jedda", - "yLabel": "2 046 300" - }, - "category": "Jedda", - "y": 2046300 - }, - { - "custom": { - "xLabel": "Sancti-Spíritus", - "yLabel": "100 751" - }, - "category": "Sancti-Spíritus", - "y": 100751 - }, - { - "custom": { - "xLabel": "Uluberia", - "yLabel": "155 172" - }, - "category": "Uluberia", - "y": 155172 - }, - { - "custom": { - "xLabel": "Huai´an", - "yLabel": "131 149" - }, - "category": "Huai´an", - "y": 131149 - }, - { - "custom": { - "xLabel": "Reno", - "yLabel": "180 480" - }, - "category": "Reno", - "y": 180480 - }, - { - "custom": { - "xLabel": "Yamuna Nagar", - "yLabel": "144 346" - }, - "category": "Yamuna Nagar", - "y": 144346 - }, - { - "custom": { - "xLabel": "Baybay", - "yLabel": "95 630" - }, - "category": "Baybay", - "y": 95630 - }, - { - "custom": { - "xLabel": "Aizuwakamatsu", - "yLabel": "119 287" - }, - "category": "Aizuwakamatsu", - "y": 119287 - }, - { - "custom": { - "xLabel": "Daloa", - "yLabel": "121 842" - }, - "category": "Daloa", - "y": 121842 - }, - { - "custom": { - "xLabel": "Kodaira", - "yLabel": "174 984" - }, - "category": "Kodaira", - "y": 174984 - }, - { - "custom": { - "xLabel": "Barletta", - "yLabel": "91 904" - }, - "category": "Barletta", - "y": 91904 - }, - { - "custom": { - "xLabel": "Bhiwani", - "yLabel": "121 629" - }, - "category": "Bhiwani", - "y": 121629 - }, - { - "custom": { - "xLabel": "Witten", - "yLabel": "103 384" - }, - "category": "Witten", - "y": 103384 - }, - { - "custom": { - "xLabel": "Bushehr", - "yLabel": "143 641" - }, - "category": "Bushehr", - "y": 143641 - }, - { - "custom": { - "xLabel": "José C. Paz", - "yLabel": "221 754" - }, - "category": "José C. Paz", - "y": 221754 - }, - { - "custom": { - "xLabel": "Dnipropetrovsk", - "yLabel": "1 103 000" - }, - "category": "Dnipropetrovsk", - "y": 1103000 - }, - { - "custom": { - "xLabel": "Probolinggo", - "yLabel": "120 770" - }, - "category": "Probolinggo", - "y": 120770 - }, - { - "custom": { - "xLabel": "Bikenibeu", - "yLabel": "5 055" - }, - "category": "Bikenibeu", - "y": 5055 - }, - { - "custom": { - "xLabel": "Oceanside", - "yLabel": "161 029" - }, - "category": "Oceanside", - "y": 161029 - }, - { - "custom": { - "xLabel": "Batna", - "yLabel": "183 377" - }, - "category": "Batna", - "y": 183377 - }, - { - "custom": { - "xLabel": "Jiangyin", - "yLabel": "213 659" - }, - "category": "Jiangyin", - "y": 213659 - }, - { - "custom": { - "xLabel": "Astana", - "yLabel": "311 200" - }, - "category": "Astana", - "y": 311200 - }, - { - "custom": { - "xLabel": "Hartford", - "yLabel": "121 578" - }, - "category": "Hartford", - "y": 121578 - }, - { - "custom": { - "xLabel": "Mangalore", - "yLabel": "273 304" - }, - "category": "Mangalore", - "y": 273304 - }, - { - "custom": { - "xLabel": "al-Arish", - "yLabel": "100 447" - }, - "category": "al-Arish", - "y": 100447 - }, - { - "custom": { - "xLabel": "Sarapul", - "yLabel": "105 700" - }, - "category": "Sarapul", - "y": 105700 - }, - { - "custom": { - "xLabel": "Karimnagar", - "yLabel": "148 583" - }, - "category": "Karimnagar", - "y": 148583 - }, - { - "custom": { - "xLabel": "Alger", - "yLabel": "2 168 000" - }, - "category": "Alger", - "y": 2168000 - }, - { - "custom": { - "xLabel": "Cilegon", - "yLabel": "117 000" - }, - "category": "Cilegon", - "y": 117000 - }, - { - "custom": { - "xLabel": "Semey", - "yLabel": "269 600" - }, - "category": "Semey", - "y": 269600 - }, - { - "custom": { - "xLabel": "Tigre", - "yLabel": "296 226" - }, - "category": "Tigre", - "y": 296226 - }, - { - "custom": { - "xLabel": "Chandler", - "yLabel": "176 581" - }, - "category": "Chandler", - "y": 176581 - }, - { - "custom": { - "xLabel": "Toulon", - "yLabel": "160 639" - }, - "category": "Toulon", - "y": 160639 - }, - { - "custom": { - "xLabel": "Hoshiarpur", - "yLabel": "122 705" - }, - "category": "Hoshiarpur", - "y": 122705 - }, - { - "custom": { - "xLabel": "Shenzhen", - "yLabel": "950 500" - }, - "category": "Shenzhen", - "y": 950500 - }, - { - "custom": { - "xLabel": "Osorno", - "yLabel": "141 468" - }, - "category": "Osorno", - "y": 141468 - }, - { - "custom": { - "xLabel": "Shikarpur", - "yLabel": "133 300" - }, - "category": "Shikarpur", - "y": 133300 - }, - { - "custom": { - "xLabel": "Ipoh", - "yLabel": "382 853" - }, - "category": "Ipoh", - "y": 382853 - }, - { - "custom": { - "xLabel": "Banja Luka", - "yLabel": "143 079" - }, - "category": "Banja Luka", - "y": 143079 - }, - { - "custom": { - "xLabel": "Narsinghdi", - "yLabel": "98 342" - }, - "category": "Narsinghdi", - "y": 98342 - }, - { - "custom": { - "xLabel": "Gejiu", - "yLabel": "214 294" - }, - "category": "Gejiu", - "y": 214294 - }, - { - "custom": { - "xLabel": "Itapevi", - "yLabel": "150 664" - }, - "category": "Itapevi", - "y": 150664 - }, - { - "custom": { - "xLabel": "Funafuti", - "yLabel": "4 600" - }, - "category": "Funafuti", - "y": 4600 - }, - { - "custom": { - "xLabel": "Gent", - "yLabel": "224 180" - }, - "category": "Gent", - "y": 224180 - }, - { - "custom": { - "xLabel": "Komsomolsk-na-Amure", - "yLabel": "291 600" - }, - "category": "Komsomolsk-na-Amure", - "y": 291600 - }, - { - "custom": { - "xLabel": "Lahore", - "yLabel": "5 063 499" - }, - "category": "Lahore", - "y": 5063499 - }, - { - "custom": { - "xLabel": "Dobric", - "yLabel": "100 399" - }, - "category": "Dobric", - "y": 100399 - }, - { - "custom": { - "xLabel": "Parañaque", - "yLabel": "449 811" - }, - "category": "Parañaque", - "y": 449811 - }, - { - "custom": { - "xLabel": "Allahabad", - "yLabel": "792 858" - }, - "category": "Allahabad", - "y": 792858 - }, - { - "custom": { - "xLabel": "Navsari", - "yLabel": "126 089" - }, - "category": "Navsari", - "y": 126089 - }, - { - "custom": { - "xLabel": "Seoul", - "yLabel": "9 981 619" - }, - "category": "Seoul", - "y": 9981619 - }, - { - "custom": { - "xLabel": "Pyongtaek", - "yLabel": "312 927" - }, - "category": "Pyongtaek", - "y": 312927 - }, - { - "custom": { - "xLabel": "Obeid", - "yLabel": "229 425" - }, - "category": "Obeid", - "y": 229425 - }, - { - "custom": { - "xLabel": "Apopa", - "yLabel": "88 800" - }, - "category": "Apopa", - "y": 88800 - }, - { - "custom": { - "xLabel": "Norrköping", - "yLabel": "122 199" - }, - "category": "Norrköping", - "y": 122199 - }, - { - "custom": { - "xLabel": "Amman", - "yLabel": "1 000 000" - }, - "category": "Amman", - "y": 1000000 - }, - { - "custom": { - "xLabel": "Xilin Hot", - "yLabel": "90 646" - }, - "category": "Xilin Hot", - "y": 90646 - }, - { - "custom": { - "xLabel": "Kure", - "yLabel": "206 504" - }, - "category": "Kure", - "y": 206504 - }, - { - "custom": { - "xLabel": "Lisboa", - "yLabel": "563 210" - }, - "category": "Lisboa", - "y": 563210 - }, - { - "custom": { - "xLabel": "Heerlen", - "yLabel": "95 052" - }, - "category": "Heerlen", - "y": 95052 - }, - { - "custom": { - "xLabel": "Abottabad", - "yLabel": "106 000" - }, - "category": "Abottabad", - "y": 106000 - }, - { - "custom": { - "xLabel": "Hirosaki", - "yLabel": "177 522" - }, - "category": "Hirosaki", - "y": 177522 - }, - { - "custom": { - "xLabel": "Takatsuki", - "yLabel": "361 747" - }, - "category": "Takatsuki", - "y": 361747 - }, - { - "custom": { - "xLabel": "Tekirdag", - "yLabel": "106 077" - }, - "category": "Tekirdag", - "y": 106077 - }, - { - "custom": { - "xLabel": "Danjiangkou", - "yLabel": "103 211" - }, - "category": "Danjiangkou", - "y": 103211 - }, - { - "custom": { - "xLabel": "Palu", - "yLabel": "142 800" - }, - "category": "Palu", - "y": 142800 - }, - { - "custom": { - "xLabel": "Irkutsk", - "yLabel": "593 700" - }, - "category": "Irkutsk", - "y": 593700 - }, - { - "custom": { - "xLabel": "Moreno Valley", - "yLabel": "142 381" - }, - "category": "Moreno Valley", - "y": 142381 - }, - { - "custom": { - "xLabel": "Thai Nguyen", - "yLabel": "127 643" - }, - "category": "Thai Nguyen", - "y": 127643 - }, - { - "custom": { - "xLabel": "Kassel", - "yLabel": "196 211" - }, - "category": "Kassel", - "y": 196211 - }, - { - "custom": { - "xLabel": "Shaoxing", - "yLabel": "179 818" - }, - "category": "Shaoxing", - "y": 179818 - }, - { - "custom": { - "xLabel": "Bakersfield", - "yLabel": "247 057" - }, - "category": "Bakersfield", - "y": 247057 - }, - { - "custom": { - "xLabel": "Pforzheim", - "yLabel": "117 227" - }, - "category": "Pforzheim", - "y": 117227 - }, - { - "custom": { - "xLabel": "Jinxi", - "yLabel": "357 052" - }, - "category": "Jinxi", - "y": 357052 - }, - { - "custom": { - "xLabel": "Peoria", - "yLabel": "112 936" - }, - "category": "Peoria", - "y": 112936 - }, - { - "custom": { - "xLabel": "Imperatriz", - "yLabel": "224 564" - }, - "category": "Imperatriz", - "y": 224564 - }, - { - "custom": { - "xLabel": "Pali", - "yLabel": "136 842" - }, - "category": "Pali", - "y": 136842 - }, - { - "custom": { - "xLabel": "Vellore", - "yLabel": "175 061" - }, - "category": "Vellore", - "y": 175061 - }, - { - "custom": { - "xLabel": "Oran", - "yLabel": "609 823" - }, - "category": "Oran", - "y": 609823 - }, - { - "custom": { - "xLabel": "Rancagua", - "yLabel": "212 977" - }, - "category": "Rancagua", - "y": 212977 - }, - { - "custom": { - "xLabel": "Témara", - "yLabel": "126 303" - }, - "category": "Témara", - "y": 126303 - }, - { - "custom": { - "xLabel": "Ciudad Valles", - "yLabel": "146 411" - }, - "category": "Ciudad Valles", - "y": 146411 - }, - { - "custom": { - "xLabel": "Kansk", - "yLabel": "107 400" - }, - "category": "Kansk", - "y": 107400 - }, - { - "custom": { - "xLabel": "Anjo", - "yLabel": "153 823" - }, - "category": "Anjo", - "y": 153823 - }, - { - "custom": { - "xLabel": "Saskatoon", - "yLabel": "193 647" - }, - "category": "Saskatoon", - "y": 193647 - }, - { - "custom": { - "xLabel": "Mexico", - "yLabel": "109 481" - }, - "category": "Mexico", - "y": 109481 - }, - { - "custom": { - "xLabel": "Kitwe", - "yLabel": "288 600" - }, - "category": "Kitwe", - "y": 288600 - }, - { - "custom": { - "xLabel": "Zaozhuang", - "yLabel": "380 846" - }, - "category": "Zaozhuang", - "y": 380846 - }, - { - "custom": { - "xLabel": "Mango", - "yLabel": "110 024" - }, - "category": "Mango", - "y": 110024 - }, - { - "custom": { - "xLabel": "Columbia", - "yLabel": "116 278" - }, - "category": "Columbia", - "y": 116278 - }, - { - "custom": { - "xLabel": "Mauá", - "yLabel": "375 055" - }, - "category": "Mauá", - "y": 375055 - }, - { - "custom": { - "xLabel": "San Felipe", - "yLabel": "90 940" - }, - "category": "San Felipe", - "y": 90940 - }, - { - "custom": { - "xLabel": "Yungkang", - "yLabel": "193 005" - }, - "category": "Yungkang", - "y": 193005 - }, - { - "custom": { - "xLabel": "Mar del Plata", - "yLabel": "512 880" - }, - "category": "Mar del Plata", - "y": 512880 - }, - { - "custom": { - "xLabel": "Kyongsan", - "yLabel": "173 746" - }, - "category": "Kyongsan", - "y": 173746 - }, - { - "custom": { - "xLabel": "Brjansk", - "yLabel": "457 400" - }, - "category": "Brjansk", - "y": 457400 - }, - { - "custom": { - "xLabel": "Benguela", - "yLabel": "128 300" - }, - "category": "Benguela", - "y": 128300 - }, - { - "custom": { - "xLabel": "Hiroshima", - "yLabel": "1 119 117" - }, - "category": "Hiroshima", - "y": 1119117 - }, - { - "custom": { - "xLabel": "Melbourne", - "yLabel": "2 865 329" - }, - "category": "Melbourne", - "y": 2865329 - }, - { - "custom": { - "xLabel": "Sachon", - "yLabel": "113 494" - }, - "category": "Sachon", - "y": 113494 - }, - { - "custom": { - "xLabel": "Henzada (Hinthada)", - "yLabel": "104 700" - }, - "category": "Henzada (Hinthada)", - "y": 104700 - }, - { - "custom": { - "xLabel": "Teresina", - "yLabel": "691 942" - }, - "category": "Teresina", - "y": 691942 - }, - { - "custom": { - "xLabel": "Kharagpur", - "yLabel": "177 989" - }, - "category": "Kharagpur", - "y": 177989 - }, - { - "custom": { - "xLabel": "Banjul", - "yLabel": "42 326" - }, - "category": "Banjul", - "y": 42326 - }, - { - "custom": { - "xLabel": "Mytištši", - "yLabel": "155 700" - }, - "category": "Mytištši", - "y": 155700 - }, - { - "custom": { - "xLabel": "Iligan", - "yLabel": "285 061" - }, - "category": "Iligan", - "y": 285061 - }, - { - "custom": { - "xLabel": "Enugu", - "yLabel": "316 100" - }, - "category": "Enugu", - "y": 316100 - }, - { - "custom": { - "xLabel": "Nigel", - "yLabel": "96 734" - }, - "category": "Nigel", - "y": 96734 - }, - { - "custom": { - "xLabel": "Elche [Elx]", - "yLabel": "193 174" - }, - "category": "Elche [Elx]", - "y": 193174 - }, - { - "custom": { - "xLabel": "Patos", - "yLabel": "90 519" - }, - "category": "Patos", - "y": 90519 - }, - { - "custom": { - "xLabel": "Weihai", - "yLabel": "128 888" - }, - "category": "Weihai", - "y": 128888 - }, - { - "custom": { - "xLabel": "Arzamas", - "yLabel": "110 700" - }, - "category": "Arzamas", - "y": 110700 - }, - { - "custom": { - "xLabel": "Port Sudan", - "yLabel": "308 195" - }, - "category": "Port Sudan", - "y": 308195 - }, - { - "custom": { - "xLabel": "Qidong", - "yLabel": "126 872" - }, - "category": "Qidong", - "y": 126872 - }, - { - "custom": { - "xLabel": "Brest", - "yLabel": "286 000" - }, - "category": "Brest", - "y": 286000 - }, - { - "custom": { - "xLabel": "Tianjin", - "yLabel": "5 286 800" - }, - "category": "Tianjin", - "y": 5286800 - }, - { - "custom": { - "xLabel": "Thessaloniki", - "yLabel": "383 967" - }, - "category": "Thessaloniki", - "y": 383967 - }, - { - "custom": { - "xLabel": "Guiyang", - "yLabel": "1 465 200" - }, - "category": "Guiyang", - "y": 1465200 - }, - { - "custom": { - "xLabel": "Ciparay", - "yLabel": "111 500" - }, - "category": "Ciparay", - "y": 111500 - }, - { - "custom": { - "xLabel": "Mozyr", - "yLabel": "110 000" - }, - "category": "Mozyr", - "y": 110000 - }, - { - "custom": { - "xLabel": "Bandar-e-Abbas", - "yLabel": "273 578" - }, - "category": "Bandar-e-Abbas", - "y": 273578 - }, - { - "custom": { - "xLabel": "Ordu", - "yLabel": "133 642" - }, - "category": "Ordu", - "y": 133642 - }, - { - "custom": { - "xLabel": "Skopje", - "yLabel": "444 299" - }, - "category": "Skopje", - "y": 444299 - }, - { - "custom": { - "xLabel": "Koronadal", - "yLabel": "133 786" - }, - "category": "Koronadal", - "y": 133786 - }, - { - "custom": { - "xLabel": "Luxembourg [Luxemburg/Lëtzebuerg]", - "yLabel": "80 700" - }, - "category": "Luxembourg [Luxemburg/Lëtzebuerg]", - "y": 80700 - }, - { - "custom": { - "xLabel": "Guaratinguetá", - "yLabel": "103 433" - }, - "category": "Guaratinguetá", - "y": 103433 - }, - { - "custom": { - "xLabel": "Le Havre", - "yLabel": "190 905" - }, - "category": "Le Havre", - "y": 190905 - }, - { - "custom": { - "xLabel": "Juazeiro", - "yLabel": "201 073" - }, - "category": "Juazeiro", - "y": 201073 - }, - { - "custom": { - "xLabel": "Wuwei", - "yLabel": "133 101" - }, - "category": "Wuwei", - "y": 133101 - }, - { - "custom": { - "xLabel": "Grand Rapids", - "yLabel": "197 800" - }, - "category": "Grand Rapids", - "y": 197800 - }, - { - "custom": { - "xLabel": "Arlington", - "yLabel": "332 969" - }, - "category": "Arlington", - "y": 332969 - }, - { - "custom": { - "xLabel": "Bukavu", - "yLabel": "201 569" - }, - "category": "Bukavu", - "y": 201569 - }, - { - "custom": { - "xLabel": "George Town", - "yLabel": "19 600" - }, - "category": "George Town", - "y": 19600 - }, - { - "custom": { - "xLabel": "Cauayan", - "yLabel": "103 952" - }, - "category": "Cauayan", - "y": 103952 - }, - { - "custom": { - "xLabel": "Derbent", - "yLabel": "92 300" - }, - "category": "Derbent", - "y": 92300 - }, - { - "custom": { - "xLabel": "Bournemouth", - "yLabel": "162 000" - }, - "category": "Bournemouth", - "y": 162000 - }, - { - "custom": { - "xLabel": "Yaizu", - "yLabel": "117 258" - }, - "category": "Yaizu", - "y": 117258 - }, - { - "custom": { - "xLabel": "Carrollton", - "yLabel": "109 576" - }, - "category": "Carrollton", - "y": 109576 - }, - { - "custom": { - "xLabel": "Aydin", - "yLabel": "128 651" - }, - "category": "Aydin", - "y": 128651 - }, - { - "custom": { - "xLabel": "Bengasi", - "yLabel": "804 000" - }, - "category": "Bengasi", - "y": 804000 - }, - { - "custom": { - "xLabel": "Pingxiang", - "yLabel": "425 579" - }, - "category": "Pingxiang", - "y": 425579 - }, - { - "custom": { - "xLabel": "Bremen", - "yLabel": "540 330" - }, - "category": "Bremen", - "y": 540330 - }, - { - "custom": { - "xLabel": "Mallawi", - "yLabel": "119 283" - }, - "category": "Mallawi", - "y": 119283 - }, - { - "custom": { - "xLabel": "Changzhi", - "yLabel": "317 144" - }, - "category": "Changzhi", - "y": 317144 - }, - { - "custom": { - "xLabel": "Hamadan", - "yLabel": "401 281" - }, - "category": "Hamadan", - "y": 401281 - }, - { - "custom": { - "xLabel": "Tanger", - "yLabel": "521 735" - }, - "category": "Tanger", - "y": 521735 - }, - { - "custom": { - "xLabel": "Santa Fé", - "yLabel": "353 063" - }, - "category": "Santa Fé", - "y": 353063 - }, - { - "custom": { - "xLabel": "Parnamirim", - "yLabel": "96 210" - }, - "category": "Parnamirim", - "y": 96210 - }, - { - "custom": { - "xLabel": "Sibiu", - "yLabel": "169 611" - }, - "category": "Sibiu", - "y": 169611 - }, - { - "custom": { - "xLabel": "Vicenza", - "yLabel": "109 738" - }, - "category": "Vicenza", - "y": 109738 - }, - { - "custom": { - "xLabel": "Danao", - "yLabel": "98 781" - }, - "category": "Danao", - "y": 98781 - }, - { - "custom": { - "xLabel": "Gabès", - "yLabel": "106 600" - }, - "category": "Gabès", - "y": 106600 - }, - { - "custom": { - "xLabel": "Poá", - "yLabel": "89 236" - }, - "category": "Poá", - "y": 89236 - }, - { - "custom": { - "xLabel": "Nueva San Salvador", - "yLabel": "98 400" - }, - "category": "Nueva San Salvador", - "y": 98400 - }, - { - "custom": { - "xLabel": "Burbank", - "yLabel": "100 316" - }, - "category": "Burbank", - "y": 100316 - }, - { - "custom": { - "xLabel": "Irbid", - "yLabel": "231 511" - }, - "category": "Irbid", - "y": 231511 - }, - { - "custom": { - "xLabel": "Nassau", - "yLabel": "172 000" - }, - "category": "Nassau", - "y": 172000 - }, - { - "custom": { - "xLabel": "Bangkok", - "yLabel": "6 320 174" - }, - "category": "Bangkok", - "y": 6320174 - }, - { - "custom": { - "xLabel": "Yangmei", - "yLabel": "126 323" - }, - "category": "Yangmei", - "y": 126323 - }, - { - "custom": { - "xLabel": "Manchester", - "yLabel": "107 006" - }, - "category": "Manchester", - "y": 107006 - }, - { - "custom": { - "xLabel": "Lafayette", - "yLabel": "110 257" - }, - "category": "Lafayette", - "y": 110257 - }, - { - "custom": { - "xLabel": "Acapulco de Juárez", - "yLabel": "721 011" - }, - "category": "Acapulco de Juárez", - "y": 721011 - }, - { - "custom": { - "xLabel": "al-Hawiya", - "yLabel": "93 900" - }, - "category": "al-Hawiya", - "y": 93900 - }, - { - "custom": { - "xLabel": "Xuangzhou", - "yLabel": "112 673" - }, - "category": "Xuangzhou", - "y": 112673 - }, - { - "custom": { - "xLabel": "Belfast", - "yLabel": "287 500" - }, - "category": "Belfast", - "y": 287500 - }, - { - "custom": { - "xLabel": "Gijón", - "yLabel": "267 980" - }, - "category": "Gijón", - "y": 267980 - }, - { - "custom": { - "xLabel": "São José de Ribamar", - "yLabel": "98 318" - }, - "category": "São José de Ribamar", - "y": 98318 - }, - { - "custom": { - "xLabel": "Le Mans", - "yLabel": "146 105" - }, - "category": "Le Mans", - "y": 146105 - }, - { - "custom": { - "xLabel": "Tiruppur (Tirupper)", - "yLabel": "235 661" - }, - "category": "Tiruppur (Tirupper)", - "y": 235661 - }, - { - "custom": { - "xLabel": "Taza", - "yLabel": "92 700" - }, - "category": "Taza", - "y": 92700 - }, - { - "custom": { - "xLabel": "Paramaribo", - "yLabel": "112 000" - }, - "category": "Paramaribo", - "y": 112000 - }, - { - "custom": { - "xLabel": "Linchuan", - "yLabel": "121 949" - }, - "category": "Linchuan", - "y": 121949 - }, - { - "custom": { - "xLabel": "San Andrés Tuxtla", - "yLabel": "142 251" - }, - "category": "San Andrés Tuxtla", - "y": 142251 - }, - { - "custom": { - "xLabel": "Pembroke Pines", - "yLabel": "137 427" - }, - "category": "Pembroke Pines", - "y": 137427 - }, - { - "custom": { - "xLabel": "Barbacena", - "yLabel": "113 079" - }, - "category": "Barbacena", - "y": 113079 - }, - { - "custom": { - "xLabel": "Nantes", - "yLabel": "270 251" - }, - "category": "Nantes", - "y": 270251 - }, - { - "custom": { - "xLabel": "Santa Catarina", - "yLabel": "226 573" - }, - "category": "Santa Catarina", - "y": 226573 - }, - { - "custom": { - "xLabel": "Chitungwiza", - "yLabel": "274 912" - }, - "category": "Chitungwiza", - "y": 274912 - }, - { - "custom": { - "xLabel": "Worcester", - "yLabel": "172 648" - }, - "category": "Worcester", - "y": 172648 - }, - { - "custom": { - "xLabel": "Balakovo", - "yLabel": "206 000" - }, - "category": "Balakovo", - "y": 206000 - }, - { - "custom": { - "xLabel": "Hebi", - "yLabel": "212 976" - }, - "category": "Hebi", - "y": 212976 - }, - { - "custom": { - "xLabel": "Binangonan", - "yLabel": "187 691" - }, - "category": "Binangonan", - "y": 187691 - }, - { - "custom": { - "xLabel": "Rudnyy", - "yLabel": "109 500" - }, - "category": "Rudnyy", - "y": 109500 - }, - { - "custom": { - "xLabel": "San Pedro", - "yLabel": "231 403" - }, - "category": "San Pedro", - "y": 231403 - }, - { - "custom": { - "xLabel": "Perm", - "yLabel": "1 009 700" - }, - "category": "Perm", - "y": 1009700 - }, - { - "custom": { - "xLabel": "Holon", - "yLabel": "163 100" - }, - "category": "Holon", - "y": 163100 - }, - { - "custom": { - "xLabel": "Štšolkovo", - "yLabel": "104 900" - }, - "category": "Štšolkovo", - "y": 104900 - }, - { - "custom": { - "xLabel": "Miraj", - "yLabel": "125 407" - }, - "category": "Miraj", - "y": 125407 - }, - { - "custom": { - "xLabel": "Haifa", - "yLabel": "265 700" - }, - "category": "Haifa", - "y": 265700 - }, - { - "custom": { - "xLabel": "Qazvin", - "yLabel": "291 117" - }, - "category": "Qazvin", - "y": 291117 - }, - { - "custom": { - "xLabel": "Salem", - "yLabel": "366 712" - }, - "category": "Salem", - "y": 366712 - }, - { - "custom": { - "xLabel": "Wichita Falls", - "yLabel": "104 197" - }, - "category": "Wichita Falls", - "y": 104197 - }, - { - "custom": { - "xLabel": "Rybinsk", - "yLabel": "239 600" - }, - "category": "Rybinsk", - "y": 239600 - }, - { - "custom": { - "xLabel": "Podgorica", - "yLabel": "135 000" - }, - "category": "Podgorica", - "y": 135000 - }, - { - "custom": { - "xLabel": "Shagamu", - "yLabel": "117 200" - }, - "category": "Shagamu", - "y": 117200 - }, - { - "custom": { - "xLabel": "Temirtau", - "yLabel": "170 500" - }, - "category": "Temirtau", - "y": 170500 - }, - { - "custom": { - "xLabel": "Sharq al-Nil", - "yLabel": "700 887" - }, - "category": "Sharq al-Nil", - "y": 700887 - }, - { - "custom": { - "xLabel": "Cochabamba", - "yLabel": "482 800" - }, - "category": "Cochabamba", - "y": 482800 - }, - { - "custom": { - "xLabel": "Indore", - "yLabel": "1 091 674" - }, - "category": "Indore", - "y": 1091674 - }, - { - "custom": { - "xLabel": "Guna", - "yLabel": "100 490" - }, - "category": "Guna", - "y": 100490 - }, - { - "custom": { - "xLabel": "Ratingen", - "yLabel": "90 951" - }, - "category": "Ratingen", - "y": 90951 - }, - { - "custom": { - "xLabel": "Bhopal", - "yLabel": "1 062 771" - }, - "category": "Bhopal", - "y": 1062771 - }, - { - "custom": { - "xLabel": "Costa Mesa", - "yLabel": "108 724" - }, - "category": "Costa Mesa", - "y": 108724 - }, - { - "custom": { - "xLabel": "Huaibei", - "yLabel": "366 549" - }, - "category": "Huaibei", - "y": 366549 - }, - { - "custom": { - "xLabel": "Nevinnomyssk", - "yLabel": "132 600" - }, - "category": "Nevinnomyssk", - "y": 132600 - }, - { - "custom": { - "xLabel": "Taoyuan", - "yLabel": "316 438" - }, - "category": "Taoyuan", - "y": 316438 - }, - { - "custom": { - "xLabel": "Zibo", - "yLabel": "1 140 000" - }, - "category": "Zibo", - "y": 1140000 - }, - { - "custom": { - "xLabel": "Neuquén", - "yLabel": "167 296" - }, - "category": "Neuquén", - "y": 167296 - }, - { - "custom": { - "xLabel": "Oranjestad", - "yLabel": "29 034" - }, - "category": "Oranjestad", - "y": 29034 - }, - { - "custom": { - "xLabel": "Vladimir", - "yLabel": "337 100" - }, - "category": "Vladimir", - "y": 337100 - }, - { - "custom": { - "xLabel": "Kumagaya", - "yLabel": "157 171" - }, - "category": "Kumagaya", - "y": 157171 - }, - { - "custom": { - "xLabel": "Salta", - "yLabel": "367 550" - }, - "category": "Salta", - "y": 367550 - }, - { - "custom": { - "xLabel": "Lubao", - "yLabel": "125 699" - }, - "category": "Lubao", - "y": 125699 - }, - { - "custom": { - "xLabel": "Brahmapur", - "yLabel": "210 418" - }, - "category": "Brahmapur", - "y": 210418 - }, - { - "custom": { - "xLabel": "Paderborn", - "yLabel": "137 647" - }, - "category": "Paderborn", - "y": 137647 - }, - { - "custom": { - "xLabel": "Hartlepool", - "yLabel": "92 000" - }, - "category": "Hartlepool", - "y": 92000 - }, - { - "custom": { - "xLabel": "Villeurbanne", - "yLabel": "124 215" - }, - "category": "Villeurbanne", - "y": 124215 - }, - { - "custom": { - "xLabel": "Rochester", - "yLabel": "219 773" - }, - "category": "Rochester", - "y": 219773 - }, - { - "custom": { - "xLabel": "Neyshabur", - "yLabel": "158 847" - }, - "category": "Neyshabur", - "y": 158847 - }, - { - "custom": { - "xLabel": "Fort Lauderdale", - "yLabel": "152 397" - }, - "category": "Fort Lauderdale", - "y": 152397 - }, - { - "custom": { - "xLabel": "Palikir", - "yLabel": "8 600" - }, - "category": "Palikir", - "y": 8600 - }, - { - "custom": { - "xLabel": "Carson", - "yLabel": "89 089" - }, - "category": "Carson", - "y": 89089 - }, - { - "custom": { - "xLabel": "Tainan", - "yLabel": "728 060" - }, - "category": "Tainan", - "y": 728060 - }, - { - "custom": { - "xLabel": "Morogoro", - "yLabel": "117 800" - }, - "category": "Morogoro", - "y": 117800 - }, - { - "custom": { - "xLabel": "Santiago de los Caballeros", - "yLabel": "365 463" - }, - "category": "Santiago de los Caballeros", - "y": 365463 - }, - { - "custom": { - "xLabel": "Khon Kaen", - "yLabel": "126 500" - }, - "category": "Khon Kaen", - "y": 126500 - }, - { - "custom": { - "xLabel": "Novi Sad", - "yLabel": "179 626" - }, - "category": "Novi Sad", - "y": 179626 - }, - { - "custom": { - "xLabel": "Guntakal", - "yLabel": "107 592" - }, - "category": "Guntakal", - "y": 107592 - }, - { - "custom": { - "xLabel": "Xalapa", - "yLabel": "390 058" - }, - "category": "Xalapa", - "y": 390058 - }, - { - "custom": { - "xLabel": "Contagem", - "yLabel": "520 801" - }, - "category": "Contagem", - "y": 520801 - }, - { - "custom": { - "xLabel": "Vadodara (Baroda)", - "yLabel": "1 031 346" - }, - "category": "Vadodara (Baroda)", - "y": 1031346 - }, - { - "custom": { - "xLabel": "Ujung Pandang", - "yLabel": "1 060 257" - }, - "category": "Ujung Pandang", - "y": 1060257 - }, - { - "custom": { - "xLabel": "Criciúma", - "yLabel": "167 661" - }, - "category": "Criciúma", - "y": 167661 - }, - { - "custom": { - "xLabel": "Jacobina", - "yLabel": "96 131" - }, - "category": "Jacobina", - "y": 96131 - }, - { - "custom": { - "xLabel": "Bochum", - "yLabel": "392 830" - }, - "category": "Bochum", - "y": 392830 - }, - { - "custom": { - "xLabel": "Butuan", - "yLabel": "267 279" - }, - "category": "Butuan", - "y": 267279 - }, - { - "custom": { - "xLabel": "Barddhaman (Burdwan)", - "yLabel": "245 079" - }, - "category": "Barddhaman (Burdwan)", - "y": 245079 - }, - { - "custom": { - "xLabel": "Jiaozuo", - "yLabel": "409 100" - }, - "category": "Jiaozuo", - "y": 409100 - }, - { - "custom": { - "xLabel": "Sakata", - "yLabel": "101 651" - }, - "category": "Sakata", - "y": 101651 - }, - { - "custom": { - "xLabel": "Mainz", - "yLabel": "183 134" - }, - "category": "Mainz", - "y": 183134 - }, - { - "custom": { - "xLabel": "Gwalior", - "yLabel": "690 765" - }, - "category": "Gwalior", - "y": 690765 - }, - { - "custom": { - "xLabel": "Norman", - "yLabel": "94 193" - }, - "category": "Norman", - "y": 94193 - }, - { - "custom": { - "xLabel": "Blackburn", - "yLabel": "140 000" - }, - "category": "Blackburn", - "y": 140000 - }, - { - "custom": { - "xLabel": "Fort-de-France", - "yLabel": "94 050" - }, - "category": "Fort-de-France", - "y": 94050 - }, - { - "custom": { - "xLabel": "Tšaikovski", - "yLabel": "90 000" - }, - "category": "Tšaikovski", - "y": 90000 - }, - { - "custom": { - "xLabel": "Jiangyou", - "yLabel": "175 753" - }, - "category": "Jiangyou", - "y": 175753 - }, - { - "custom": { - "xLabel": "Changsha", - "yLabel": "1 809 800" - }, - "category": "Changsha", - "y": 1809800 - }, - { - "custom": { - "xLabel": "Tiaret", - "yLabel": "100 118" - }, - "category": "Tiaret", - "y": 100118 - }, - { - "custom": { - "xLabel": "Latakia", - "yLabel": "264 563" - }, - "category": "Latakia", - "y": 264563 - }, - { - "custom": { - "xLabel": "Tanauan", - "yLabel": "117 539" - }, - "category": "Tanauan", - "y": 117539 - }, - { - "custom": { - "xLabel": "Braunschweig", - "yLabel": "246 322" - }, - "category": "Braunschweig", - "y": 246322 - }, - { - "custom": { - "xLabel": "Neyveli", - "yLabel": "118 080" - }, - "category": "Neyveli", - "y": 118080 - }, - { - "custom": { - "xLabel": "Sunderland", - "yLabel": "183 310" - }, - "category": "Sunderland", - "y": 183310 - }, - { - "custom": { - "xLabel": "Kilis", - "yLabel": "118 245" - }, - "category": "Kilis", - "y": 118245 - }, - { - "custom": { - "xLabel": "Addis Abeba", - "yLabel": "2 495 000" - }, - "category": "Addis Abeba", - "y": 2495000 - }, - { - "custom": { - "xLabel": "Monaco-Ville", - "yLabel": "1 234" - }, - "category": "Monaco-Ville", - "y": 1234 - }, - { - "custom": { - "xLabel": "Hanoi", - "yLabel": "1 410 000" - }, - "category": "Hanoi", - "y": 1410000 - }, - { - "custom": { - "xLabel": "East York", - "yLabel": "114 034" - }, - "category": "East York", - "y": 114034 - }, - { - "custom": { - "xLabel": "Parakou", - "yLabel": "103 577" - }, - "category": "Parakou", - "y": 103577 - }, - { - "custom": { - "xLabel": "Tsuruoka", - "yLabel": "100 713" - }, - "category": "Tsuruoka", - "y": 100713 - }, - { - "custom": { - "xLabel": "Vitória", - "yLabel": "270 626" - }, - "category": "Vitória", - "y": 270626 - }, - { - "custom": { - "xLabel": "Santo André", - "yLabel": "630 073" - }, - "category": "Santo André", - "y": 630073 - }, - { - "custom": { - "xLabel": "Quetzaltenango", - "yLabel": "90 801" - }, - "category": "Quetzaltenango", - "y": 90801 - }, - { - "custom": { - "xLabel": "Jubayl", - "yLabel": "140 800" - }, - "category": "Jubayl", - "y": 140800 - }, - { - "custom": { - "xLabel": "Unnao", - "yLabel": "107 425" - }, - "category": "Unnao", - "y": 107425 - }, - { - "custom": { - "xLabel": "Moriguchi", - "yLabel": "155 941" - }, - "category": "Moriguchi", - "y": 155941 - }, - { - "custom": { - "xLabel": "Khujand", - "yLabel": "161 500" - }, - "category": "Khujand", - "y": 161500 - }, - { - "custom": { - "xLabel": "Esmeraldas", - "yLabel": "123 045" - }, - "category": "Esmeraldas", - "y": 123045 - }, - { - "custom": { - "xLabel": "Cuiabá", - "yLabel": "453 813" - }, - "category": "Cuiabá", - "y": 453813 - }, - { - "custom": { - "xLabel": "Parma", - "yLabel": "168 717" - }, - "category": "Parma", - "y": 168717 - }, - { - "custom": { - "xLabel": "Atlanta", - "yLabel": "416 474" - }, - "category": "Atlanta", - "y": 416474 - }, - { - "custom": { - "xLabel": "Ageo", - "yLabel": "209 442" - }, - "category": "Ageo", - "y": 209442 - }, - { - "custom": { - "xLabel": "Mingäçevir", - "yLabel": "93 900" - }, - "category": "Mingäçevir", - "y": 93900 - }, - { - "custom": { - "xLabel": "Donetsk", - "yLabel": "1 050 000" - }, - "category": "Donetsk", - "y": 1050000 - }, - { - "custom": { - "xLabel": "Danyang", - "yLabel": "169 603" - }, - "category": "Danyang", - "y": 169603 - }, - { - "custom": { - "xLabel": "Taldyqorghan", - "yLabel": "98 000" - }, - "category": "Taldyqorghan", - "y": 98000 - }, - { - "custom": { - "xLabel": "Vancouver", - "yLabel": "514 008" - }, - "category": "Vancouver", - "y": 514008 - }, - { - "custom": { - "xLabel": "Aligarh", - "yLabel": "480 520" - }, - "category": "Aligarh", - "y": 480520 - }, - { - "custom": { - "xLabel": "Çorlu", - "yLabel": "123 300" - }, - "category": "Çorlu", - "y": 123300 - }, - { - "custom": { - "xLabel": "Nanning", - "yLabel": "1 161 800" - }, - "category": "Nanning", - "y": 1161800 - }, - { - "custom": { - "xLabel": "Sumy", - "yLabel": "294 000" - }, - "category": "Sumy", - "y": 294000 - }, - { - "custom": { - "xLabel": "San Miguelito", - "yLabel": "315 382" - }, - "category": "San Miguelito", - "y": 315382 - }, - { - "custom": { - "xLabel": "Narayanganj", - "yLabel": "202 134" - }, - "category": "Narayanganj", - "y": 202134 - }, - { - "custom": { - "xLabel": "New Haven", - "yLabel": "123 626" - }, - "category": "New Haven", - "y": 123626 - }, - { - "custom": { - "xLabel": "Balašov", - "yLabel": "97 100" - }, - "category": "Balašov", - "y": 97100 - }, - { - "custom": { - "xLabel": "Salavat", - "yLabel": "156 800" - }, - "category": "Salavat", - "y": 156800 - }, - { - "custom": { - "xLabel": "Ploiesti", - "yLabel": "251 348" - }, - "category": "Ploiesti", - "y": 251348 - }, - { - "custom": { - "xLabel": "Mersin (Içel)", - "yLabel": "587 212" - }, - "category": "Mersin (Içel)", - "y": 587212 - }, - { - "custom": { - "xLabel": "Meerut Cantonment", - "yLabel": "94 876" - }, - "category": "Meerut Cantonment", - "y": 94876 - }, - { - "custom": { - "xLabel": "Mekele", - "yLabel": "96 938" - }, - "category": "Mekele", - "y": 96938 - }, - { - "custom": { - "xLabel": "Bujumbura", - "yLabel": "300 000" - }, - "category": "Bujumbura", - "y": 300000 - }, - { - "custom": { - "xLabel": "Bucaramanga", - "yLabel": "515 555" - }, - "category": "Bucaramanga", - "y": 515555 - }, - { - "custom": { - "xLabel": "Marrakech", - "yLabel": "621 914" - }, - "category": "Marrakech", - "y": 621914 - }, - { - "custom": { - "xLabel": "Yungho", - "yLabel": "227 700" - }, - "category": "Yungho", - "y": 227700 - }, - { - "custom": { - "xLabel": "Port-Vila", - "yLabel": "33 700" - }, - "category": "Port-Vila", - "y": 33700 - }, - { - "custom": { - "xLabel": "Oviedo", - "yLabel": "200 453" - }, - "category": "Oviedo", - "y": 200453 - }, - { - "custom": { - "xLabel": "Santiago de Compostela", - "yLabel": "93 745" - }, - "category": "Santiago de Compostela", - "y": 93745 - }, - { - "custom": { - "xLabel": "Rangpur", - "yLabel": "191 398" - }, - "category": "Rangpur", - "y": 191398 - }, - { - "custom": { - "xLabel": "Varna", - "yLabel": "299 801" - }, - "category": "Varna", - "y": 299801 - }, - { - "custom": { - "xLabel": "Taipei", - "yLabel": "2 641 312" - }, - "category": "Taipei", - "y": 2641312 - }, - { - "custom": { - "xLabel": "Minneapolis", - "yLabel": "382 618" - }, - "category": "Minneapolis", - "y": 382618 - }, - { - "custom": { - "xLabel": "Kushiro", - "yLabel": "197 608" - }, - "category": "Kushiro", - "y": 197608 - }, - { - "custom": { - "xLabel": "Tšeljabinsk", - "yLabel": "1 083 200" - }, - "category": "Tšeljabinsk", - "y": 1083200 - }, - { - "custom": { - "xLabel": "Oshawa", - "yLabel": "140 173" - }, - "category": "Oshawa", - "y": 140173 - }, - { - "custom": { - "xLabel": "Dundee", - "yLabel": "146 690" - }, - "category": "Dundee", - "y": 146690 - }, - { - "custom": { - "xLabel": "Markham", - "yLabel": "189 098" - }, - "category": "Markham", - "y": 189098 - }, - { - "custom": { - "xLabel": "Lima", - "yLabel": "6 464 693" - }, - "category": "Lima", - "y": 6464693 - }, - { - "custom": { - "xLabel": "Brampton", - "yLabel": "296 711" - }, - "category": "Brampton", - "y": 296711 - }, - { - "custom": { - "xLabel": "Boksburg", - "yLabel": "262 648" - }, - "category": "Boksburg", - "y": 262648 - }, - { - "custom": { - "xLabel": "Colorado Springs", - "yLabel": "360 890" - }, - "category": "Colorado Springs", - "y": 360890 - }, - { - "custom": { - "xLabel": "St-Étienne", - "yLabel": "180 210" - }, - "category": "St-Étienne", - "y": 180210 - }, - { - "custom": { - "xLabel": "Regina", - "yLabel": "180 400" - }, - "category": "Regina", - "y": 180400 - }, - { - "custom": { - "xLabel": "Randfontein", - "yLabel": "120 838" - }, - "category": "Randfontein", - "y": 120838 - }, - { - "custom": { - "xLabel": "Koblenz", - "yLabel": "108 003" - }, - "category": "Koblenz", - "y": 108003 - }, - { - "custom": { - "xLabel": "Kurgan", - "yLabel": "364 700" - }, - "category": "Kurgan", - "y": 364700 - }, - { - "custom": { - "xLabel": "Shambajinagar (Aurangabad)", - "yLabel": "573 272" - }, - "category": "Shambajinagar (Aurangabad)", - "y": 573272 - }, - { - "custom": { - "xLabel": "Fernando de la Mora", - "yLabel": "95 287" - }, - "category": "Fernando de la Mora", - "y": 95287 - }, - { - "custom": { - "xLabel": "Otsu", - "yLabel": "282 070" - }, - "category": "Otsu", - "y": 282070 - }, - { - "custom": { - "xLabel": "Jalib al-Shuyukh", - "yLabel": "102 178" - }, - "category": "Jalib al-Shuyukh", - "y": 102178 - }, - { - "custom": { - "xLabel": "Rui´an", - "yLabel": "156 468" - }, - "category": "Rui´an", - "y": 156468 - }, - { - "custom": { - "xLabel": "Kudus", - "yLabel": "95 300" - }, - "category": "Kudus", - "y": 95300 - }, - { - "custom": { - "xLabel": "Mariupol", - "yLabel": "490 000" - }, - "category": "Mariupol", - "y": 490000 - }, - { - "custom": { - "xLabel": "Mykolajiv", - "yLabel": "508 000" - }, - "category": "Mykolajiv", - "y": 508000 - }, - { - "custom": { - "xLabel": "Moreno", - "yLabel": "356 993" - }, - "category": "Moreno", - "y": 356993 - }, - { - "custom": { - "xLabel": "Khulna", - "yLabel": "663 340" - }, - "category": "Khulna", - "y": 663340 - }, - { - "custom": { - "xLabel": "Béjaïa", - "yLabel": "117 162" - }, - "category": "Béjaïa", - "y": 117162 - }, - { - "custom": { - "xLabel": "Nonsan", - "yLabel": "146 619" - }, - "category": "Nonsan", - "y": 146619 - }, - { - "custom": { - "xLabel": "Mataram", - "yLabel": "306 600" - }, - "category": "Mataram", - "y": 306600 - }, - { - "custom": { - "xLabel": "Louisville", - "yLabel": "256 231" - }, - "category": "Louisville", - "y": 256231 - }, - { - "custom": { - "xLabel": "Rahim Yar Khan", - "yLabel": "228 479" - }, - "category": "Rahim Yar Khan", - "y": 228479 - }, - { - "custom": { - "xLabel": "Haiphong", - "yLabel": "783 133" - }, - "category": "Haiphong", - "y": 783133 - }, - { - "custom": { - "xLabel": "Enschede", - "yLabel": "149 544" - }, - "category": "Enschede", - "y": 149544 - }, - { - "custom": { - "xLabel": "Palmira", - "yLabel": "226 509" - }, - "category": "Palmira", - "y": 226509 - }, - { - "custom": { - "xLabel": "Apodaca", - "yLabel": "282 941" - }, - "category": "Apodaca", - "y": 282941 - }, - { - "custom": { - "xLabel": "Elektrostal", - "yLabel": "147 000" - }, - "category": "Elektrostal", - "y": 147000 - }, - { - "custom": { - "xLabel": "Amarillo", - "yLabel": "173 627" - }, - "category": "Amarillo", - "y": 173627 - }, - { - "custom": { - "xLabel": "Barnaul", - "yLabel": "580 100" - }, - "category": "Barnaul", - "y": 580100 - }, - { - "custom": { - "xLabel": "Zacatecas", - "yLabel": "123 700" - }, - "category": "Zacatecas", - "y": 123700 - }, - { - "custom": { - "xLabel": "Halisahar", - "yLabel": "114 028" - }, - "category": "Halisahar", - "y": 114028 - }, - { - "custom": { - "xLabel": "Nottingham", - "yLabel": "287 000" - }, - "category": "Nottingham", - "y": 287000 - }, - { - "custom": { - "xLabel": "Pondok Aren", - "yLabel": "92 700" - }, - "category": "Pondok Aren", - "y": 92700 - }, - { - "custom": { - "xLabel": "al-Minya", - "yLabel": "201 360" - }, - "category": "al-Minya", - "y": 201360 - }, - { - "custom": { - "xLabel": "Mianyang", - "yLabel": "262 947" - }, - "category": "Mianyang", - "y": 262947 - }, - { - "custom": { - "xLabel": "Benoni", - "yLabel": "365 467" - }, - "category": "Benoni", - "y": 365467 - }, - { - "custom": { - "xLabel": "Cascavel", - "yLabel": "237 510" - }, - "category": "Cascavel", - "y": 237510 - }, - { - "custom": { - "xLabel": "Almere", - "yLabel": "142 465" - }, - "category": "Almere", - "y": 142465 - }, - { - "custom": { - "xLabel": "Baia Mare", - "yLabel": "149 665" - }, - "category": "Baia Mare", - "y": 149665 - }, - { - "custom": { - "xLabel": "Morioka", - "yLabel": "287 353" - }, - "category": "Morioka", - "y": 287353 - }, - { - "custom": { - "xLabel": "São Paulo", - "yLabel": "9 968 485" - }, - "category": "São Paulo", - "y": 9968485 - }, - { - "custom": { - "xLabel": "Zapopan", - "yLabel": "1 002 239" - }, - "category": "Zapopan", - "y": 1002239 - }, - { - "custom": { - "xLabel": "Cuddapah", - "yLabel": "121 463" - }, - "category": "Cuddapah", - "y": 121463 - }, - { - "custom": { - "xLabel": "Bahía Blanca", - "yLabel": "239 810" - }, - "category": "Bahía Blanca", - "y": 239810 - }, - { - "custom": { - "xLabel": "Fuyu", - "yLabel": "192 981" - }, - "category": "Fuyu", - "y": 192981 - }, - { - "custom": { - "xLabel": "Saint Helens", - "yLabel": "106 293" - }, - "category": "Saint Helens", - "y": 106293 - }, - { - "custom": { - "xLabel": "Tacoma", - "yLabel": "193 556" - }, - "category": "Tacoma", - "y": 193556 - }, - { - "custom": { - "xLabel": "Czestochowa", - "yLabel": "257 812" - }, - "category": "Czestochowa", - "y": 257812 - }, - { - "custom": { - "xLabel": "Suizhou", - "yLabel": "142 302" - }, - "category": "Suizhou", - "y": 142302 - }, - { - "custom": { - "xLabel": "San Miguel de Tucumán", - "yLabel": "470 809" - }, - "category": "San Miguel de Tucumán", - "y": 470809 - }, - { - "custom": { - "xLabel": "Rijeka", - "yLabel": "167 964" - }, - "category": "Rijeka", - "y": 167964 - }, - { - "custom": { - "xLabel": "Suwon", - "yLabel": "755 550" - }, - "category": "Suwon", - "y": 755550 - }, - { - "custom": { - "xLabel": "Zixing", - "yLabel": "110 048" - }, - "category": "Zixing", - "y": 110048 - }, - { - "custom": { - "xLabel": "Obninsk", - "yLabel": "108 300" - }, - "category": "Obninsk", - "y": 108300 - }, - { - "custom": { - "xLabel": "Paulo Afonso", - "yLabel": "97 291" - }, - "category": "Paulo Afonso", - "y": 97291 - }, - { - "custom": { - "xLabel": "Magadan", - "yLabel": "121 000" - }, - "category": "Magadan", - "y": 121000 - }, - { - "custom": { - "xLabel": "São Gonçalo", - "yLabel": "869 254" - }, - "category": "São Gonçalo", - "y": 869254 - }, - { - "custom": { - "xLabel": "Delft", - "yLabel": "95 268" - }, - "category": "Delft", - "y": 95268 - }, - { - "custom": { - "xLabel": "Ourinhos", - "yLabel": "96 291" - }, - "category": "Ourinhos", - "y": 96291 - }, - { - "custom": { - "xLabel": "Naogaon", - "yLabel": "101 266" - }, - "category": "Naogaon", - "y": 101266 - }, - { - "custom": { - "xLabel": "Kanggye", - "yLabel": "223 410" - }, - "category": "Kanggye", - "y": 223410 - }, - { - "custom": { - "xLabel": "Jekaterinburg", - "yLabel": "1 266 300" - }, - "category": "Jekaterinburg", - "y": 1266300 - }, - { - "custom": { - "xLabel": "Magé", - "yLabel": "196 147" - }, - "category": "Magé", - "y": 196147 - }, - { - "custom": { - "xLabel": "Cebu", - "yLabel": "718 821" - }, - "category": "Cebu", - "y": 718821 - }, - { - "custom": { - "xLabel": "Votkinsk", - "yLabel": "101 700" - }, - "category": "Votkinsk", - "y": 101700 - }, - { - "custom": { - "xLabel": "Biñan", - "yLabel": "201 186" - }, - "category": "Biñan", - "y": 201186 - }, - { - "custom": { - "xLabel": "Lomas de Zamora", - "yLabel": "622 013" - }, - "category": "Lomas de Zamora", - "y": 622013 - }, - { - "custom": { - "xLabel": "Panabo", - "yLabel": "133 950" - }, - "category": "Panabo", - "y": 133950 - }, - { - "custom": { - "xLabel": "Kostroma", - "yLabel": "288 100" - }, - "category": "Kostroma", - "y": 288100 - }, - { - "custom": { - "xLabel": "Kisumu", - "yLabel": "192 733" - }, - "category": "Kisumu", - "y": 192733 - }, - { - "custom": { - "xLabel": "Aix-en-Provence", - "yLabel": "134 222" - }, - "category": "Aix-en-Provence", - "y": 134222 - }, - { - "custom": { - "xLabel": "Guarulhos", - "yLabel": "1 095 874" - }, - "category": "Guarulhos", - "y": 1095874 - }, - { - "custom": { - "xLabel": "Ilesha", - "yLabel": "378 400" - }, - "category": "Ilesha", - "y": 378400 - }, - { - "custom": { - "xLabel": "Craiova", - "yLabel": "313 530" - }, - "category": "Craiova", - "y": 313530 - }, - { - "custom": { - "xLabel": "Kanton [Guangzhou]", - "yLabel": "4 256 300" - }, - "category": "Kanton [Guangzhou]", - "y": 4256300 - }, - { - "custom": { - "xLabel": "Gaborone", - "yLabel": "213 017" - }, - "category": "Gaborone", - "y": 213017 - }, - { - "custom": { - "xLabel": "Thunder Bay", - "yLabel": "115 913" - }, - "category": "Thunder Bay", - "y": 115913 - }, - { - "custom": { - "xLabel": "Pachuca de Soto", - "yLabel": "244 688" - }, - "category": "Pachuca de Soto", - "y": 244688 - }, - { - "custom": { - "xLabel": "Nanchang", - "yLabel": "1 691 600" - }, - "category": "Nanchang", - "y": 1691600 - }, - { - "custom": { - "xLabel": "Jember", - "yLabel": "218 500" - }, - "category": "Jember", - "y": 218500 - }, - { - "custom": { - "xLabel": "Charlotte Amalie", - "yLabel": "13 000" - }, - "category": "Charlotte Amalie", - "y": 13000 - }, - { - "custom": { - "xLabel": "Bacabal", - "yLabel": "93 121" - }, - "category": "Bacabal", - "y": 93121 - }, - { - "custom": { - "xLabel": "Musashino", - "yLabel": "134 426" - }, - "category": "Musashino", - "y": 134426 - }, - { - "custom": { - "xLabel": "Lucena", - "yLabel": "196 075" - }, - "category": "Lucena", - "y": 196075 - }, - { - "custom": { - "xLabel": "Witbank", - "yLabel": "167 183" - }, - "category": "Witbank", - "y": 167183 - }, - { - "custom": { - "xLabel": "Kongju", - "yLabel": "131 229" - }, - "category": "Kongju", - "y": 131229 - }, - { - "custom": { - "xLabel": "Bulawayo", - "yLabel": "621 742" - }, - "category": "Bulawayo", - "y": 621742 - }, - { - "custom": { - "xLabel": "Chilpancingo de los Bravo", - "yLabel": "192 509" - }, - "category": "Chilpancingo de los Bravo", - "y": 192509 - }, - { - "custom": { - "xLabel": "Ibaraki", - "yLabel": "261 020" - }, - "category": "Ibaraki", - "y": 261020 - }, - { - "custom": { - "xLabel": "Jinzhou", - "yLabel": "95 761" - }, - "category": "Jinzhou", - "y": 95761 - }, - { - "custom": { - "xLabel": "Clarksville", - "yLabel": "108 787" - }, - "category": "Clarksville", - "y": 108787 - }, - { - "custom": { - "xLabel": "Honghu", - "yLabel": "190 772" - }, - "category": "Honghu", - "y": 190772 - }, - { - "custom": { - "xLabel": "Gravataí", - "yLabel": "223 011" - }, - "category": "Gravataí", - "y": 223011 - }, - { - "custom": { - "xLabel": "Taiyuan", - "yLabel": "1 968 400" - }, - "category": "Taiyuan", - "y": 1968400 - }, - { - "custom": { - "xLabel": "Yueyang", - "yLabel": "302 800" - }, - "category": "Yueyang", - "y": 302800 - }, - { - "custom": { - "xLabel": "Izmajil", - "yLabel": "90 000" - }, - "category": "Izmajil", - "y": 90000 - }, - { - "custom": { - "xLabel": "Mönchengladbach", - "yLabel": "263 697" - }, - "category": "Mönchengladbach", - "y": 263697 - }, - { - "custom": { - "xLabel": "Ashikaga", - "yLabel": "165 243" - }, - "category": "Ashikaga", - "y": 165243 - }, - { - "custom": { - "xLabel": "Alandur", - "yLabel": "125 244" - }, - "category": "Alandur", - "y": 125244 - }, - { - "custom": { - "xLabel": "Makurdi", - "yLabel": "123 100" - }, - "category": "Makurdi", - "y": 123100 - }, - { - "custom": { - "xLabel": "Târgu Jiu", - "yLabel": "98 524" - }, - "category": "Târgu Jiu", - "y": 98524 - }, - { - "custom": { - "xLabel": "Queimados", - "yLabel": "115 020" - }, - "category": "Queimados", - "y": 115020 - }, - { - "custom": { - "xLabel": "Talcahuano", - "yLabel": "277 752" - }, - "category": "Talcahuano", - "y": 277752 - }, - { - "custom": { - "xLabel": "Chesapeake", - "yLabel": "199 184" - }, - "category": "Chesapeake", - "y": 199184 - }, - { - "custom": { - "xLabel": "Munger (Monghyr)", - "yLabel": "150 112" - }, - "category": "Munger (Monghyr)", - "y": 150112 - }, - { - "custom": { - "xLabel": "Soledad", - "yLabel": "295 058" - }, - "category": "Soledad", - "y": 295058 - }, - { - "custom": { - "xLabel": "Guacara", - "yLabel": "131 334" - }, - "category": "Guacara", - "y": 131334 - }, - { - "custom": { - "xLabel": "Warangal", - "yLabel": "447 657" - }, - "category": "Warangal", - "y": 447657 - }, - { - "custom": { - "xLabel": "Nanping", - "yLabel": "195 064" - }, - "category": "Nanping", - "y": 195064 - }, - { - "custom": { - "xLabel": "Berdytšiv", - "yLabel": "90 000" - }, - "category": "Berdytšiv", - "y": 90000 - }, - { - "custom": { - "xLabel": "Kertš", - "yLabel": "162 000" - }, - "category": "Kertš", - "y": 162000 - }, - { - "custom": { - "xLabel": "Dos Quebradas", - "yLabel": "159 363" - }, - "category": "Dos Quebradas", - "y": 159363 - }, - { - "custom": { - "xLabel": "Várzea Grande", - "yLabel": "214 435" - }, - "category": "Várzea Grande", - "y": 214435 - }, - { - "custom": { - "xLabel": "Soyapango", - "yLabel": "129 800" - }, - "category": "Soyapango", - "y": 129800 - }, - { - "custom": { - "xLabel": "Changhwa", - "yLabel": "227 715" - }, - "category": "Changhwa", - "y": 227715 - }, - { - "custom": { - "xLabel": "Leiyang", - "yLabel": "130 115" - }, - "category": "Leiyang", - "y": 130115 - }, - { - "custom": { - "xLabel": "Beawar", - "yLabel": "105 363" - }, - "category": "Beawar", - "y": 105363 - }, - { - "custom": { - "xLabel": "Kursk", - "yLabel": "443 500" - }, - "category": "Kursk", - "y": 443500 - }, - { - "custom": { - "xLabel": "Sunnyvale", - "yLabel": "131 760" - }, - "category": "Sunnyvale", - "y": 131760 - }, - { - "custom": { - "xLabel": "Luanda", - "yLabel": "2 022 000" - }, - "category": "Luanda", - "y": 2022000 - }, - { - "custom": { - "xLabel": "Sergijev Posad", - "yLabel": "111 100" - }, - "category": "Sergijev Posad", - "y": 111100 - }, - { - "custom": { - "xLabel": "Visalia", - "yLabel": "91 762" - }, - "category": "Visalia", - "y": 91762 - }, - { - "custom": { - "xLabel": "Isesaki", - "yLabel": "123 285" - }, - "category": "Isesaki", - "y": 123285 - }, - { - "custom": { - "xLabel": "Jequié", - "yLabel": "179 128" - }, - "category": "Jequié", - "y": 179128 - }, - { - "custom": { - "xLabel": "San Miguel", - "yLabel": "248 700" - }, - "category": "San Miguel", - "y": 248700 - }, - { - "custom": { - "xLabel": "Inglewood", - "yLabel": "112 580" - }, - "category": "Inglewood", - "y": 112580 - }, - { - "custom": { - "xLabel": "Padang", - "yLabel": "534 474" - }, - "category": "Padang", - "y": 534474 - }, - { - "custom": { - "xLabel": "Laoag", - "yLabel": "94 466" - }, - "category": "Laoag", - "y": 94466 - }, - { - "custom": { - "xLabel": "Caucaia", - "yLabel": "238 738" - }, - "category": "Caucaia", - "y": 238738 - }, - { - "custom": { - "xLabel": "Kwangju", - "yLabel": "1 368 341" - }, - "category": "Kwangju", - "y": 1368341 - }, - { - "custom": { - "xLabel": "Sanaa", - "yLabel": "503 600" - }, - "category": "Sanaa", - "y": 503600 - }, - { - "custom": { - "xLabel": "Jiutepec", - "yLabel": "170 428" - }, - "category": "Jiutepec", - "y": 170428 - }, - { - "custom": { - "xLabel": "Othón P. Blanco (Chetumal)", - "yLabel": "208 014" - }, - "category": "Othón P. Blanco (Chetumal)", - "y": 208014 - }, - { - "custom": { - "xLabel": "Adelaide", - "yLabel": "978 100" - }, - "category": "Adelaide", - "y": 978100 - }, - { - "custom": { - "xLabel": "Marília", - "yLabel": "188 691" - }, - "category": "Marília", - "y": 188691 - }, - { - "custom": { - "xLabel": "Ashgabat", - "yLabel": "540 600" - }, - "category": "Ashgabat", - "y": 540600 - }, - { - "custom": { - "xLabel": "Junan", - "yLabel": "90 222" - }, - "category": "Junan", - "y": 90222 - }, - { - "custom": { - "xLabel": "Drobeta-Turnu Severin", - "yLabel": "117 865" - }, - "category": "Drobeta-Turnu Severin", - "y": 117865 - }, - { - "custom": { - "xLabel": "Iskenderun", - "yLabel": "153 022" - }, - "category": "Iskenderun", - "y": 153022 - }, - { - "custom": { - "xLabel": "Sibu", - "yLabel": "126 381" - }, - "category": "Sibu", - "y": 126381 - }, - { - "custom": { - "xLabel": "Anqing", - "yLabel": "250 718" - }, - "category": "Anqing", - "y": 250718 - }, - { - "custom": { - "xLabel": "São João de Meriti", - "yLabel": "440 052" - }, - "category": "São João de Meriti", - "y": 440052 - }, - { - "custom": { - "xLabel": "Ebina", - "yLabel": "115 571" - }, - "category": "Ebina", - "y": 115571 - }, - { - "custom": { - "xLabel": "Usolje-Sibirskoje", - "yLabel": "103 500" - }, - "category": "Usolje-Sibirskoje", - "y": 103500 - }, - { - "custom": { - "xLabel": "Plock", - "yLabel": "131 011" - }, - "category": "Plock", - "y": 131011 - }, - { - "custom": { - "xLabel": "Ahmedabad", - "yLabel": "2 876 710" - }, - "category": "Ahmedabad", - "y": 2876710 - }, - { - "custom": { - "xLabel": "Canoas", - "yLabel": "294 125" - }, - "category": "Canoas", - "y": 294125 - }, - { - "custom": { - "xLabel": "Mushin", - "yLabel": "333 200" - }, - "category": "Mushin", - "y": 333200 - }, - { - "custom": { - "xLabel": "Siem Reap", - "yLabel": "105 100" - }, - "category": "Siem Reap", - "y": 105100 - }, - { - "custom": { - "xLabel": "Jaya Pura", - "yLabel": "94 700" - }, - "category": "Jaya Pura", - "y": 94700 - }, - { - "custom": { - "xLabel": "Agaña", - "yLabel": "1 139" - }, - "category": "Agaña", - "y": 1139 - }, - { - "custom": { - "xLabel": "San Jose", - "yLabel": "111 009" - }, - "category": "San Jose", - "y": 111009 - }, - { - "custom": { - "xLabel": "Mumbai (Bombay)", - "yLabel": "10 500 000" - }, - "category": "Mumbai (Bombay)", - "y": 10500000 - }, - { - "custom": { - "xLabel": "Matola", - "yLabel": "424 662" - }, - "category": "Matola", - "y": 424662 - }, - { - "custom": { - "xLabel": "Coímbra", - "yLabel": "96 100" - }, - "category": "Coímbra", - "y": 96100 - }, - { - "custom": { - "xLabel": "Liverpool", - "yLabel": "461 000" - }, - "category": "Liverpool", - "y": 461000 - }, - { - "custom": { - "xLabel": "Debrecen", - "yLabel": "203 648" - }, - "category": "Debrecen", - "y": 203648 - }, - { - "custom": { - "xLabel": "Birgunj", - "yLabel": "90 639" - }, - "category": "Birgunj", - "y": 90639 - }, - { - "custom": { - "xLabel": "Ongole", - "yLabel": "100 836" - }, - "category": "Ongole", - "y": 100836 - }, - { - "custom": { - "xLabel": "Angeles", - "yLabel": "263 971" - }, - "category": "Angeles", - "y": 263971 - }, - { - "custom": { - "xLabel": "New Bombay", - "yLabel": "307 297" - }, - "category": "New Bombay", - "y": 307297 - }, - { - "custom": { - "xLabel": "Chemnitz", - "yLabel": "263 222" - }, - "category": "Chemnitz", - "y": 263222 - }, - { - "custom": { - "xLabel": "Beppu", - "yLabel": "127 486" - }, - "category": "Beppu", - "y": 127486 - }, - { - "custom": { - "xLabel": "Bilaspur", - "yLabel": "179 833" - }, - "category": "Bilaspur", - "y": 179833 - }, - { - "custom": { - "xLabel": "Abuja", - "yLabel": "350 100" - }, - "category": "Abuja", - "y": 350100 - }, - { - "custom": { - "xLabel": "São José dos Campos", - "yLabel": "515 553" - }, - "category": "São José dos Campos", - "y": 515553 - }, - { - "custom": { - "xLabel": "Jiaonan", - "yLabel": "121 397" - }, - "category": "Jiaonan", - "y": 121397 - }, - { - "custom": { - "xLabel": "Nishio", - "yLabel": "100 032" - }, - "category": "Nishio", - "y": 100032 - }, - { - "custom": { - "xLabel": "Soledad de Graciano Sánchez", - "yLabel": "179 956" - }, - "category": "Soledad de Graciano Sánchez", - "y": 179956 - }, - { - "custom": { - "xLabel": "New Delhi", - "yLabel": "301 297" - }, - "category": "New Delhi", - "y": 301297 - }, - { - "custom": { - "xLabel": "Davao", - "yLabel": "1 147 116" - }, - "category": "Davao", - "y": 1147116 - }, - { - "custom": { - "xLabel": "Balikesir", - "yLabel": "196 382" - }, - "category": "Balikesir", - "y": 196382 - }, - { - "custom": { - "xLabel": "Itajaí", - "yLabel": "145 197" - }, - "category": "Itajaí", - "y": 145197 - }, - { - "custom": { - "xLabel": "Komaki", - "yLabel": "139 827" - }, - "category": "Komaki", - "y": 139827 - }, - { - "custom": { - "xLabel": "Zumpango", - "yLabel": "99 781" - }, - "category": "Zumpango", - "y": 99781 - }, - { - "custom": { - "xLabel": "Kurume", - "yLabel": "235 611" - }, - "category": "Kurume", - "y": 235611 - }, - { - "custom": { - "xLabel": "Basseterre", - "yLabel": "11 600" - }, - "category": "Basseterre", - "y": 11600 - }, - { - "custom": { - "xLabel": "Aden", - "yLabel": "398 300" - }, - "category": "Aden", - "y": 398300 - }, - { - "custom": { - "xLabel": "San Lorenzo", - "yLabel": "133 395" - }, - "category": "San Lorenzo", - "y": 133395 - }, - { - "custom": { - "xLabel": "Xinzhou", - "yLabel": "98 667" - }, - "category": "Xinzhou", - "y": 98667 - }, - { - "custom": { - "xLabel": "Riyadh", - "yLabel": "3 324 000" - }, - "category": "Riyadh", - "y": 3324000 - }, - { - "custom": { - "xLabel": "Dehri", - "yLabel": "94 526" - }, - "category": "Dehri", - "y": 94526 - }, - { - "custom": { - "xLabel": "Mahatškala", - "yLabel": "332 800" - }, - "category": "Mahatškala", - "y": 332800 - }, - { - "custom": { - "xLabel": "Weinan", - "yLabel": "140 169" - }, - "category": "Weinan", - "y": 140169 - }, - { - "custom": { - "xLabel": "Honiara", - "yLabel": "50 100" - }, - "category": "Honiara", - "y": 50100 - }, - { - "custom": { - "xLabel": "San Juan del Río", - "yLabel": "179 300" - }, - "category": "San Juan del Río", - "y": 179300 - }, - { - "custom": { - "xLabel": "Kumbakonam", - "yLabel": "139 483" - }, - "category": "Kumbakonam", - "y": 139483 - }, - { - "custom": { - "xLabel": "Diyarbakir", - "yLabel": "479 884" - }, - "category": "Diyarbakir", - "y": 479884 - }, - { - "custom": { - "xLabel": "Fengcheng", - "yLabel": "193 784" - }, - "category": "Fengcheng", - "y": 193784 - }, - { - "custom": { - "xLabel": "Isehara", - "yLabel": "98 123" - }, - "category": "Isehara", - "y": 98123 - }, - { - "custom": { - "xLabel": "Qaemshahr", - "yLabel": "143 286" - }, - "category": "Qaemshahr", - "y": 143286 - }, - { - "custom": { - "xLabel": "Bradford", - "yLabel": "289 376" - }, - "category": "Bradford", - "y": 289376 - }, - { - "custom": { - "xLabel": "Sakarya (Adapazari)", - "yLabel": "190 641" - }, - "category": "Sakarya (Adapazari)", - "y": 190641 - }, - { - "custom": { - "xLabel": "Longyan", - "yLabel": "134 481" - }, - "category": "Longyan", - "y": 134481 - }, - { - "custom": { - "xLabel": "Alanya", - "yLabel": "117 300" - }, - "category": "Alanya", - "y": 117300 - }, - { - "custom": { - "xLabel": "Santa Cruz de la Sierra", - "yLabel": "935 361" - }, - "category": "Santa Cruz de la Sierra", - "y": 935361 - }, - { - "custom": { - "xLabel": "Anyang", - "yLabel": "420 332" - }, - "category": "Anyang", - "y": 420332 - }, - { - "custom": { - "xLabel": "Koszalin", - "yLabel": "112 375" - }, - "category": "Koszalin", - "y": 112375 - }, - { - "custom": { - "xLabel": "Lansing", - "yLabel": "119 128" - }, - "category": "Lansing", - "y": 119128 - }, - { - "custom": { - "xLabel": "Aomori", - "yLabel": "295 969" - }, - "category": "Aomori", - "y": 295969 - }, - { - "custom": { - "xLabel": "Tamale", - "yLabel": "151 069" - }, - "category": "Tamale", - "y": 151069 - }, - { - "custom": { - "xLabel": "North Las Vegas", - "yLabel": "115 488" - }, - "category": "North Las Vegas", - "y": 115488 - }, - { - "custom": { - "xLabel": "Ulanhot", - "yLabel": "159 538" - }, - "category": "Ulanhot", - "y": 159538 - }, - { - "custom": { - "xLabel": "Mombasa", - "yLabel": "461 753" - }, - "category": "Mombasa", - "y": 461753 - }, - { - "custom": { - "xLabel": "Izumi", - "yLabel": "166 979" - }, - "category": "Izumi", - "y": 166979 - }, - { - "custom": { - "xLabel": "La Plata", - "yLabel": "521 936" - }, - "category": "La Plata", - "y": 521936 - }, - { - "custom": { - "xLabel": "Puente Alto", - "yLabel": "386 236" - }, - "category": "Puente Alto", - "y": 386236 - }, - { - "custom": { - "xLabel": "Percut Sei Tuan", - "yLabel": "129 000" - }, - "category": "Percut Sei Tuan", - "y": 129000 - }, - { - "custom": { - "xLabel": "Rangoon (Yangon)", - "yLabel": "3 361 700" - }, - "category": "Rangoon (Yangon)", - "y": 3361700 - }, - { - "custom": { - "xLabel": "Caxias", - "yLabel": "133 980" - }, - "category": "Caxias", - "y": 133980 - }, - { - "custom": { - "xLabel": "Pune", - "yLabel": "1 566 651" - }, - "category": "Pune", - "y": 1566651 - }, - { - "custom": { - "xLabel": "Maiduguri", - "yLabel": "320 000" - }, - "category": "Maiduguri", - "y": 320000 - }, - { - "custom": { - "xLabel": "Amsterdam", - "yLabel": "731 200" - }, - "category": "Amsterdam", - "y": 731200 - }, - { - "custom": { - "xLabel": "Pyongyang", - "yLabel": "2 484 000" - }, - "category": "Pyongyang", - "y": 2484000 - }, - { - "custom": { - "xLabel": "Xining", - "yLabel": "700 200" - }, - "category": "Xining", - "y": 700200 - }, - { - "custom": { - "xLabel": "Meikhtila", - "yLabel": "129 700" - }, - "category": "Meikhtila", - "y": 129700 - }, - { - "custom": { - "xLabel": "Hamilton", - "yLabel": "117 100" - }, - "category": "Hamilton", - "y": 117100 - }, - { - "custom": { - "xLabel": "Kashiwa", - "yLabel": "320 296" - }, - "category": "Kashiwa", - "y": 320296 - }, - { - "custom": { - "xLabel": "Gaziantep", - "yLabel": "789 056" - }, - "category": "Gaziantep", - "y": 789056 - }, - { - "custom": { - "xLabel": "Taunggyi (Taunggye)", - "yLabel": "131 500" - }, - "category": "Taunggyi (Taunggye)", - "y": 131500 - }, - { - "custom": { - "xLabel": "Hakodate", - "yLabel": "294 788" - }, - "category": "Hakodate", - "y": 294788 - }, - { - "custom": { - "xLabel": "Stockton", - "yLabel": "243 771" - }, - "category": "Stockton", - "y": 243771 - }, - { - "custom": { - "xLabel": "al-Qadarif", - "yLabel": "191 164" - }, - "category": "al-Qadarif", - "y": 191164 - }, - { - "custom": { - "xLabel": "Kwangmyong", - "yLabel": "350 914" - }, - "category": "Kwangmyong", - "y": 350914 - }, - { - "custom": { - "xLabel": "Hangzhou", - "yLabel": "2 190 500" - }, - "category": "Hangzhou", - "y": 2190500 - }, - { - "custom": { - "xLabel": "Osnabrück", - "yLabel": "164 539" - }, - "category": "Osnabrück", - "y": 164539 - }, - { - "custom": { - "xLabel": "Zagazig", - "yLabel": "267 351" - }, - "category": "Zagazig", - "y": 267351 - }, - { - "custom": { - "xLabel": "Zhuhai", - "yLabel": "164 747" - }, - "category": "Zhuhai", - "y": 164747 - }, - { - "custom": { - "xLabel": "Daqing", - "yLabel": "660 000" - }, - "category": "Daqing", - "y": 660000 - }, - { - "custom": { - "xLabel": "Tongling", - "yLabel": "228 017" - }, - "category": "Tongling", - "y": 228017 - }, - { - "custom": { - "xLabel": "Ji´an", - "yLabel": "148 583" - }, - "category": "Ji´an", - "y": 148583 - }, - { - "custom": { - "xLabel": "Birkenhead", - "yLabel": "93 087" - }, - "category": "Birkenhead", - "y": 93087 - }, - { - "custom": { - "xLabel": "Cartago", - "yLabel": "125 884" - }, - "category": "Cartago", - "y": 125884 - }, - { - "custom": { - "xLabel": "Proddatur", - "yLabel": "133 914" - }, - "category": "Proddatur", - "y": 133914 - }, - { - "custom": { - "xLabel": "Irving", - "yLabel": "191 615" - }, - "category": "Irving", - "y": 191615 - }, - { - "custom": { - "xLabel": "Aqsu", - "yLabel": "164 092" - }, - "category": "Aqsu", - "y": 164092 - }, - { - "custom": { - "xLabel": "Jhansi", - "yLabel": "300 850" - }, - "category": "Jhansi", - "y": 300850 - }, - { - "custom": { - "xLabel": "Puerto La Cruz", - "yLabel": "155 700" - }, - "category": "Puerto La Cruz", - "y": 155700 - }, - { - "custom": { - "xLabel": "Southport", - "yLabel": "90 959" - }, - "category": "Southport", - "y": 90959 - }, - { - "custom": { - "xLabel": "Ambato", - "yLabel": "169 612" - }, - "category": "Ambato", - "y": 169612 - }, - { - "custom": { - "xLabel": "Armenia", - "yLabel": "288 977" - }, - "category": "Armenia", - "y": 288977 - }, - { - "custom": { - "xLabel": "Vladikavkaz", - "yLabel": "310 100" - }, - "category": "Vladikavkaz", - "y": 310100 - }, - { - "custom": { - "xLabel": "Tampere", - "yLabel": "195 468" - }, - "category": "Tampere", - "y": 195468 - }, - { - "custom": { - "xLabel": "San Fernando", - "yLabel": "102 082" - }, - "category": "San Fernando", - "y": 102082 - }, - { - "custom": { - "xLabel": "Chapecó", - "yLabel": "144 158" - }, - "category": "Chapecó", - "y": 144158 - }, - { - "custom": { - "xLabel": "Tychy", - "yLabel": "133 178" - }, - "category": "Tychy", - "y": 133178 - }, - { - "custom": { - "xLabel": "Tuticorin", - "yLabel": "199 854" - }, - "category": "Tuticorin", - "y": 199854 - }, - { - "custom": { - "xLabel": "Liaocheng", - "yLabel": "207 844" - }, - "category": "Liaocheng", - "y": 207844 - }, - { - "custom": { - "xLabel": "Malungon", - "yLabel": "93 232" - }, - "category": "Malungon", - "y": 93232 - }, - { - "custom": { - "xLabel": "Teheran", - "yLabel": "6 758 845" - }, - "category": "Teheran", - "y": 6758845 - }, - { - "custom": { - "xLabel": "Gadag Betigeri", - "yLabel": "134 051" - }, - "category": "Gadag Betigeri", - "y": 134051 - }, - { - "custom": { - "xLabel": "Hongjiang", - "yLabel": "116 188" - }, - "category": "Hongjiang", - "y": 116188 - }, - { - "custom": { - "xLabel": "Santa Bárbara d´Oeste", - "yLabel": "171 657" - }, - "category": "Santa Bárbara d´Oeste", - "y": 171657 - }, - { - "custom": { - "xLabel": "Lleida (Lérida)", - "yLabel": "112 207" - }, - "category": "Lleida (Lérida)", - "y": 112207 - }, - { - "custom": { - "xLabel": "Siirt", - "yLabel": "107 100" - }, - "category": "Siirt", - "y": 107100 - }, - { - "custom": { - "xLabel": "Orehovo-Zujevo", - "yLabel": "124 900" - }, - "category": "Orehovo-Zujevo", - "y": 124900 - }, - { - "custom": { - "xLabel": "Paarl", - "yLabel": "105 768" - }, - "category": "Paarl", - "y": 105768 - }, - { - "custom": { - "xLabel": "Belgorod", - "yLabel": "342 000" - }, - "category": "Belgorod", - "y": 342000 - }, - { - "custom": { - "xLabel": "Dresden", - "yLabel": "476 668" - }, - "category": "Dresden", - "y": 476668 - }, - { - "custom": { - "xLabel": "Gillingham", - "yLabel": "92 000" - }, - "category": "Gillingham", - "y": 92000 - }, - { - "custom": { - "xLabel": "Indaiatuba", - "yLabel": "135 968" - }, - "category": "Indaiatuba", - "y": 135968 - }, - { - "custom": { - "xLabel": "Vila Velha", - "yLabel": "318 758" - }, - "category": "Vila Velha", - "y": 318758 - }, - { - "custom": { - "xLabel": "Jastrzebie-Zdrój", - "yLabel": "102 294" - }, - "category": "Jastrzebie-Zdrój", - "y": 102294 - }, - { - "custom": { - "xLabel": "Yingkou", - "yLabel": "421 589" - }, - "category": "Yingkou", - "y": 421589 - }, - { - "custom": { - "xLabel": "Ponce", - "yLabel": "186 475" - }, - "category": "Ponce", - "y": 186475 - }, - { - "custom": { - "xLabel": "Hortolândia", - "yLabel": "135 755" - }, - "category": "Hortolândia", - "y": 135755 - }, - { - "custom": { - "xLabel": "Toljatti", - "yLabel": "722 900" - }, - "category": "Toljatti", - "y": 722900 - }, - { - "custom": { - "xLabel": "Provo", - "yLabel": "105 166" - }, - "category": "Provo", - "y": 105166 - }, - { - "custom": { - "xLabel": "Vizianagaram", - "yLabel": "160 359" - }, - "category": "Vizianagaram", - "y": 160359 - }, - { - "custom": { - "xLabel": "Yumen", - "yLabel": "109 234" - }, - "category": "Yumen", - "y": 109234 - }, - { - "custom": { - "xLabel": "Tšeboksary", - "yLabel": "459 200" - }, - "category": "Tšeboksary", - "y": 459200 - }, - { - "custom": { - "xLabel": "Darbhanga", - "yLabel": "218 391" - }, - "category": "Darbhanga", - "y": 218391 - }, - { - "custom": { - "xLabel": "Constanta", - "yLabel": "342 264" - }, - "category": "Constanta", - "y": 342264 - }, - { - "custom": { - "xLabel": "Guadalupe", - "yLabel": "108 881" - }, - "category": "Guadalupe", - "y": 108881 - }, - { - "custom": { - "xLabel": "Mazar-e-Sharif", - "yLabel": "127 800" - }, - "category": "Mazar-e-Sharif", - "y": 127800 - }, - { - "custom": { - "xLabel": "Kangshan", - "yLabel": "92 200" - }, - "category": "Kangshan", - "y": 92200 - }, - { - "custom": { - "xLabel": "Xiangfan", - "yLabel": "410 407" - }, - "category": "Xiangfan", - "y": 410407 - }, - { - "custom": { - "xLabel": "Wenzhou", - "yLabel": "401 871" - }, - "category": "Wenzhou", - "y": 401871 - }, - { - "custom": { - "xLabel": "Shimoga", - "yLabel": "179 258" - }, - "category": "Shimoga", - "y": 179258 - }, - { - "custom": { - "xLabel": "Tula", - "yLabel": "506 100" - }, - "category": "Tula", - "y": 506100 - }, - { - "custom": { - "xLabel": "Nellore", - "yLabel": "316 606" - }, - "category": "Nellore", - "y": 316606 - }, - { - "custom": { - "xLabel": "Siliguri (Shiliguri)", - "yLabel": "216 950" - }, - "category": "Siliguri (Shiliguri)", - "y": 216950 - }, - { - "custom": { - "xLabel": "Linz", - "yLabel": "188 022" - }, - "category": "Linz", - "y": 188022 - }, - { - "custom": { - "xLabel": "Larkana", - "yLabel": "270 366" - }, - "category": "Larkana", - "y": 270366 - }, - { - "custom": { - "xLabel": "Leeds", - "yLabel": "424 194" - }, - "category": "Leeds", - "y": 424194 - }, - { - "custom": { - "xLabel": "San Luis Río Colorado", - "yLabel": "145 276" - }, - "category": "San Luis Río Colorado", - "y": 145276 - }, - { - "custom": { - "xLabel": "Bolzano", - "yLabel": "97 232" - }, - "category": "Bolzano", - "y": 97232 - }, - { - "custom": { - "xLabel": "Velbert", - "yLabel": "89 881" - }, - "category": "Velbert", - "y": 89881 - }, - { - "custom": { - "xLabel": "Deyang", - "yLabel": "182 488" - }, - "category": "Deyang", - "y": 182488 - }, - { - "custom": { - "xLabel": "Sétif", - "yLabel": "179 055" - }, - "category": "Sétif", - "y": 179055 - }, - { - "custom": { - "xLabel": "Glendale", - "yLabel": "218 812" - }, - "category": "Glendale", - "y": 218812 - }, - { - "custom": { - "xLabel": "Brighton", - "yLabel": "156 124" - }, - "category": "Brighton", - "y": 156124 - }, - { - "custom": { - "xLabel": "Kahramanmaras", - "yLabel": "245 772" - }, - "category": "Kahramanmaras", - "y": 245772 - }, - { - "custom": { - "xLabel": "Iida", - "yLabel": "107 583" - }, - "category": "Iida", - "y": 107583 - }, - { - "custom": { - "xLabel": "Mahabad", - "yLabel": "107 799" - }, - "category": "Mahabad", - "y": 107799 - }, - { - "custom": { - "xLabel": "Concepción", - "yLabel": "217 664" - }, - "category": "Concepción", - "y": 217664 - }, - { - "custom": { - "xLabel": "Ivano-Frankivsk", - "yLabel": "237 000" - }, - "category": "Ivano-Frankivsk", - "y": 237000 - }, - { - "custom": { - "xLabel": "San Marino", - "yLabel": "2 294" - }, - "category": "San Marino", - "y": 2294 - }, - { - "custom": { - "xLabel": "Berlin", - "yLabel": "3 386 667" - }, - "category": "Berlin", - "y": 3386667 - }, - { - "custom": { - "xLabel": "Tabaco", - "yLabel": "107 166" - }, - "category": "Tabaco", - "y": 107166 - }, - { - "custom": { - "xLabel": "Catanduva", - "yLabel": "107 761" - }, - "category": "Catanduva", - "y": 107761 - }, - { - "custom": { - "xLabel": "Bareilly", - "yLabel": "587 211" - }, - "category": "Bareilly", - "y": 587211 - }, - { - "custom": { - "xLabel": "São Lourenço da Mata", - "yLabel": "91 999" - }, - "category": "São Lourenço da Mata", - "y": 91999 - }, - { - "custom": { - "xLabel": "Hubli-Dharwad", - "yLabel": "648 298" - }, - "category": "Hubli-Dharwad", - "y": 648298 - }, - { - "custom": { - "xLabel": "Celaya", - "yLabel": "382 140" - }, - "category": "Celaya", - "y": 382140 - }, - { - "custom": { - "xLabel": "Edinburgh", - "yLabel": "450 180" - }, - "category": "Edinburgh", - "y": 450180 - }, - { - "custom": { - "xLabel": "Piracicaba", - "yLabel": "319 104" - }, - "category": "Piracicaba", - "y": 319104 - }, - { - "custom": { - "xLabel": "Blagoveštšensk", - "yLabel": "222 000" - }, - "category": "Blagoveštšensk", - "y": 222000 - }, - { - "custom": { - "xLabel": "Toda", - "yLabel": "103 969" - }, - "category": "Toda", - "y": 103969 - }, - { - "custom": { - "xLabel": "Le-Cap-Haïtien", - "yLabel": "102 233" - }, - "category": "Le-Cap-Haïtien", - "y": 102233 - }, - { - "custom": { - "xLabel": "Xinyang", - "yLabel": "192 509" - }, - "category": "Xinyang", - "y": 192509 - }, - { - "custom": { - "xLabel": "Kanazawa", - "yLabel": "455 386" - }, - "category": "Kanazawa", - "y": 455386 - }, - { - "custom": { - "xLabel": "Irapuato", - "yLabel": "440 039" - }, - "category": "Irapuato", - "y": 440039 - }, - { - "custom": { - "xLabel": "Minoo", - "yLabel": "127 026" - }, - "category": "Minoo", - "y": 127026 - }, - { - "custom": { - "xLabel": "Bogor", - "yLabel": "285 114" - }, - "category": "Bogor", - "y": 285114 - }, - { - "custom": { - "xLabel": "Kiziltepe", - "yLabel": "112 000" - }, - "category": "Kiziltepe", - "y": 112000 - }, - { - "custom": { - "xLabel": "Los Angeles", - "yLabel": "158 215" - }, - "category": "Los Angeles", - "y": 158215 - }, - { - "custom": { - "xLabel": "Sidi Bel Abbès", - "yLabel": "153 106" - }, - "category": "Sidi Bel Abbès", - "y": 153106 - }, - { - "custom": { - "xLabel": "Hsintien", - "yLabel": "263 603" - }, - "category": "Hsintien", - "y": 263603 - }, - { - "custom": { - "xLabel": "Pingliang", - "yLabel": "99 265" - }, - "category": "Pingliang", - "y": 99265 - }, - { - "custom": { - "xLabel": "Soshanguve", - "yLabel": "242 727" - }, - "category": "Soshanguve", - "y": 242727 - }, - { - "custom": { - "xLabel": "Ferraz de Vasconcelos", - "yLabel": "139 283" - }, - "category": "Ferraz de Vasconcelos", - "y": 139283 - }, - { - "custom": { - "xLabel": "Changzhou", - "yLabel": "530 000" - }, - "category": "Changzhou", - "y": 530000 - }, - { - "custom": { - "xLabel": "Port-Louis", - "yLabel": "138 200" - }, - "category": "Port-Louis", - "y": 138200 - }, - { - "custom": { - "xLabel": "Donostia-San Sebastián", - "yLabel": "179 208" - }, - "category": "Donostia-San Sebastián", - "y": 179208 - }, - { - "custom": { - "xLabel": "Owo", - "yLabel": "183 500" - }, - "category": "Owo", - "y": 183500 - }, - { - "custom": { - "xLabel": "Gandhinagar", - "yLabel": "123 359" - }, - "category": "Gandhinagar", - "y": 123359 - }, - { - "custom": { - "xLabel": "Cairo", - "yLabel": "6 789 479" - }, - "category": "Cairo", - "y": 6789479 - }, - { - "custom": { - "xLabel": "Bhatinda (Bathinda)", - "yLabel": "159 042" - }, - "category": "Bhatinda (Bathinda)", - "y": 159042 - }, - { - "custom": { - "xLabel": "Gold Coast", - "yLabel": "311 932" - }, - "category": "Gold Coast", - "y": 311932 - }, - { - "custom": { - "xLabel": "Berdjansk", - "yLabel": "130 000" - }, - "category": "Berdjansk", - "y": 130000 - }, - { - "custom": { - "xLabel": "Santander", - "yLabel": "184 165" - }, - "category": "Santander", - "y": 184165 - }, - { - "custom": { - "xLabel": "Cedar Rapids", - "yLabel": "120 758" - }, - "category": "Cedar Rapids", - "y": 120758 - }, - { - "custom": { - "xLabel": "Itabira", - "yLabel": "102 217" - }, - "category": "Itabira", - "y": 102217 - }, - { - "custom": { - "xLabel": "Savannakhet", - "yLabel": "96 652" - }, - "category": "Savannakhet", - "y": 96652 - }, - { - "custom": { - "xLabel": "Karaj", - "yLabel": "940 968" - }, - "category": "Karaj", - "y": 940968 - }, - { - "custom": { - "xLabel": "Bilbays", - "yLabel": "113 608" - }, - "category": "Bilbays", - "y": 113608 - }, - { - "custom": { - "xLabel": "Recklinghausen", - "yLabel": "125 022" - }, - "category": "Recklinghausen", - "y": 125022 - }, - { - "custom": { - "xLabel": "Anchorage", - "yLabel": "260 283" - }, - "category": "Anchorage", - "y": 260283 - }, - { - "custom": { - "xLabel": "Fengyuan", - "yLabel": "161 032" - }, - "category": "Fengyuan", - "y": 161032 - }, - { - "custom": { - "xLabel": "Norfolk", - "yLabel": "234 403" - }, - "category": "Norfolk", - "y": 234403 - }, - { - "custom": { - "xLabel": "Kunshan", - "yLabel": "102 052" - }, - "category": "Kunshan", - "y": 102052 - }, - { - "custom": { - "xLabel": "Dubai", - "yLabel": "669 181" - }, - "category": "Dubai", - "y": 669181 - }, - { - "custom": { - "xLabel": "San Bernardo", - "yLabel": "241 910" - }, - "category": "San Bernardo", - "y": 241910 - }, - { - "custom": { - "xLabel": "Nicolás Romero", - "yLabel": "269 393" - }, - "category": "Nicolás Romero", - "y": 269393 - }, - { - "custom": { - "xLabel": "Edmonton", - "yLabel": "616 306" - }, - "category": "Edmonton", - "y": 616306 - }, - { - "custom": { - "xLabel": "Jaffna", - "yLabel": "149 000" - }, - "category": "Jaffna", - "y": 149000 - }, - { - "custom": { - "xLabel": "Eunápolis", - "yLabel": "96 610" - }, - "category": "Eunápolis", - "y": 96610 - }, - { - "custom": { - "xLabel": "Lianyuan", - "yLabel": "118 858" - }, - "category": "Lianyuan", - "y": 118858 - }, - { - "custom": { - "xLabel": "Hagonoy", - "yLabel": "111 425" - }, - "category": "Hagonoy", - "y": 111425 - }, - { - "custom": { - "xLabel": "al-Mukalla", - "yLabel": "122 400" - }, - "category": "al-Mukalla", - "y": 122400 - }, - { - "custom": { - "xLabel": "Gdansk", - "yLabel": "458 988" - }, - "category": "Gdansk", - "y": 458988 - }, - { - "custom": { - "xLabel": "Anzero-Sudzensk", - "yLabel": "96 100" - }, - "category": "Anzero-Sudzensk", - "y": 96100 - }, - { - "custom": { - "xLabel": "Fujieda", - "yLabel": "126 897" - }, - "category": "Fujieda", - "y": 126897 - }, - { - "custom": { - "xLabel": "al-Sulaymaniya", - "yLabel": "364 096" - }, - "category": "al-Sulaymaniya", - "y": 364096 - }, - { - "custom": { - "xLabel": "Midsayap", - "yLabel": "105 760" - }, - "category": "Midsayap", - "y": 105760 - }, - { - "custom": { - "xLabel": "Clearwater", - "yLabel": "99 936" - }, - "category": "Clearwater", - "y": 99936 - }, - { - "custom": { - "xLabel": "Kumi", - "yLabel": "311 431" - }, - "category": "Kumi", - "y": 311431 - }, - { - "custom": { - "xLabel": "Agartala", - "yLabel": "157 358" - }, - "category": "Agartala", - "y": 157358 - }, - { - "custom": { - "xLabel": "Arad", - "yLabel": "184 408" - }, - "category": "Arad", - "y": 184408 - }, - { - "custom": { - "xLabel": "Valparai", - "yLabel": "106 523" - }, - "category": "Valparai", - "y": 106523 - }, - { - "custom": { - "xLabel": "Torrance", - "yLabel": "137 946" - }, - "category": "Torrance", - "y": 137946 - }, - { - "custom": { - "xLabel": "Tokyo", - "yLabel": "7 980 230" - }, - "category": "Tokyo", - "y": 7980230 - }, - { - "custom": { - "xLabel": "Luzhou", - "yLabel": "262 892" - }, - "category": "Luzhou", - "y": 262892 - }, - { - "custom": { - "xLabel": "Sheffield", - "yLabel": "431 607" - }, - "category": "Sheffield", - "y": 431607 - }, - { - "custom": { - "xLabel": "Kingston", - "yLabel": "800" - }, - "category": "Kingston", - "y": 800 - }, - { - "custom": { - "xLabel": "Plymouth", - "yLabel": "2 000" - }, - "category": "Plymouth", - "y": 2000 - }, - { - "custom": { - "xLabel": "Ibb", - "yLabel": "103 300" - }, - "category": "Ibb", - "y": 103300 - }, - { - "custom": { - "xLabel": "Cuenca", - "yLabel": "270 353" - }, - "category": "Cuenca", - "y": 270353 - }, - { - "custom": { - "xLabel": "Bila Tserkva", - "yLabel": "215 000" - }, - "category": "Bila Tserkva", - "y": 215000 - }, - { - "custom": { - "xLabel": "Windsor", - "yLabel": "207 588" - }, - "category": "Windsor", - "y": 207588 - }, - { - "custom": { - "xLabel": "Glendale", - "yLabel": "194 973" - }, - "category": "Glendale", - "y": 194973 - }, - { - "custom": { - "xLabel": "Kelowna", - "yLabel": "89 442" - }, - "category": "Kelowna", - "y": 89442 - }, - { - "custom": { - "xLabel": "Ezeiza", - "yLabel": "99 578" - }, - "category": "Ezeiza", - "y": 99578 - }, - { - "custom": { - "xLabel": "Toamasina", - "yLabel": "127 441" - }, - "category": "Toamasina", - "y": 127441 - }, - { - "custom": { - "xLabel": "Gojra", - "yLabel": "115 000" - }, - "category": "Gojra", - "y": 115000 - }, - { - "custom": { - "xLabel": "Columbus", - "yLabel": "711 470" - }, - "category": "Columbus", - "y": 711470 - }, - { - "custom": { - "xLabel": "Biserta", - "yLabel": "108 900" - }, - "category": "Biserta", - "y": 108900 - }, - { - "custom": { - "xLabel": "Sunrise Manor", - "yLabel": "95 362" - }, - "category": "Sunrise Manor", - "y": 95362 - }, - { - "custom": { - "xLabel": "Águas Lindas de Goiás", - "yLabel": "89 200" - }, - "category": "Águas Lindas de Goiás", - "y": 89200 - }, - { - "custom": { - "xLabel": "Bataisk", - "yLabel": "97 300" - }, - "category": "Bataisk", - "y": 97300 - }, - { - "custom": { - "xLabel": "Vacoas-Phoenix", - "yLabel": "98 464" - }, - "category": "Vacoas-Phoenix", - "y": 98464 - }, - { - "custom": { - "xLabel": "Manado", - "yLabel": "332 288" - }, - "category": "Manado", - "y": 332288 - }, - { - "custom": { - "xLabel": "Ontario", - "yLabel": "158 007" - }, - "category": "Ontario", - "y": 158007 - }, - { - "custom": { - "xLabel": "Arezzo", - "yLabel": "91 729" - }, - "category": "Arezzo", - "y": 91729 - }, - { - "custom": { - "xLabel": "Andria", - "yLabel": "94 443" - }, - "category": "Andria", - "y": 94443 - }, - { - "custom": { - "xLabel": "Karnal", - "yLabel": "173 751" - }, - "category": "Karnal", - "y": 173751 - }, - { - "custom": { - "xLabel": "Longjing", - "yLabel": "139 417" - }, - "category": "Longjing", - "y": 139417 - }, - { - "custom": { - "xLabel": "Sanchung", - "yLabel": "380 084" - }, - "category": "Sanchung", - "y": 380084 - }, - { - "custom": { - "xLabel": "Arusha", - "yLabel": "102 500" - }, - "category": "Arusha", - "y": 102500 - }, - { - "custom": { - "xLabel": "Jirja", - "yLabel": "95 400" - }, - "category": "Jirja", - "y": 95400 - }, - { - "custom": { - "xLabel": "Hat Yai", - "yLabel": "148 632" - }, - "category": "Hat Yai", - "y": 148632 - }, - { - "custom": { - "xLabel": "Mahbubnagar", - "yLabel": "116 833" - }, - "category": "Mahbubnagar", - "y": 116833 - }, - { - "custom": { - "xLabel": "Cavite", - "yLabel": "99 367" - }, - "category": "Cavite", - "y": 99367 - }, - { - "custom": { - "xLabel": "Kawanishi", - "yLabel": "149 794" - }, - "category": "Kawanishi", - "y": 149794 - }, - { - "custom": { - "xLabel": "Bassein (Pathein)", - "yLabel": "183 900" - }, - "category": "Bassein (Pathein)", - "y": 183900 - }, - { - "custom": { - "xLabel": "Kinshasa", - "yLabel": "5 064 000" - }, - "category": "Kinshasa", - "y": 5064000 - }, - { - "custom": { - "xLabel": "Raurkela Civil Township", - "yLabel": "140 408" - }, - "category": "Raurkela Civil Township", - "y": 140408 - }, - { - "custom": { - "xLabel": "Nancy", - "yLabel": "103 605" - }, - "category": "Nancy", - "y": 103605 - }, - { - "custom": { - "xLabel": "Naha", - "yLabel": "299 851" - }, - "category": "Naha", - "y": 299851 - }, - { - "custom": { - "xLabel": "Kabul", - "yLabel": "1 780 000" - }, - "category": "Kabul", - "y": 1780000 - }, - { - "custom": { - "xLabel": "Hathras", - "yLabel": "113 285" - }, - "category": "Hathras", - "y": 113285 - }, - { - "custom": { - "xLabel": "Remscheid", - "yLabel": "120 125" - }, - "category": "Remscheid", - "y": 120125 - }, - { - "custom": { - "xLabel": "Ranchi", - "yLabel": "599 306" - }, - "category": "Ranchi", - "y": 599306 - }, - { - "custom": { - "xLabel": "Oberholzer", - "yLabel": "164 367" - }, - "category": "Oberholzer", - "y": 164367 - }, - { - "custom": { - "xLabel": "Linhai", - "yLabel": "90 870" - }, - "category": "Linhai", - "y": 90870 - }, - { - "custom": { - "xLabel": "Araçatuba", - "yLabel": "169 303" - }, - "category": "Araçatuba", - "y": 169303 - }, - { - "custom": { - "xLabel": "Osijek", - "yLabel": "104 761" - }, - "category": "Osijek", - "y": 104761 - }, - { - "custom": { - "xLabel": "Balikpapan", - "yLabel": "338 752" - }, - "category": "Balikpapan", - "y": 338752 - }, - { - "custom": { - "xLabel": "Kragujevac", - "yLabel": "147 305" - }, - "category": "Kragujevac", - "y": 147305 - }, - { - "custom": { - "xLabel": "Béchar", - "yLabel": "107 311" - }, - "category": "Béchar", - "y": 107311 - }, - { - "custom": { - "xLabel": "Grand Prairie", - "yLabel": "127 427" - }, - "category": "Grand Prairie", - "y": 127427 - }, - { - "custom": { - "xLabel": "Naucalpan de Juárez", - "yLabel": "857 511" - }, - "category": "Naucalpan de Juárez", - "y": 857511 - }, - { - "custom": { - "xLabel": "Dalian", - "yLabel": "2 697 000" - }, - "category": "Dalian", - "y": 2697000 - }, - { - "custom": { - "xLabel": "York", - "yLabel": "154 980" - }, - "category": "York", - "y": 154980 - }, - { - "custom": { - "xLabel": "Lünen", - "yLabel": "92 044" - }, - "category": "Lünen", - "y": 92044 - }, - { - "custom": { - "xLabel": "Chonju", - "yLabel": "563 153" - }, - "category": "Chonju", - "y": 563153 - }, - { - "custom": { - "xLabel": "Gandhidham", - "yLabel": "104 585" - }, - "category": "Gandhidham", - "y": 104585 - }, - { - "custom": { - "xLabel": "Naga", - "yLabel": "137 810" - }, - "category": "Naga", - "y": 137810 - }, - { - "custom": { - "xLabel": "Kukatpalle", - "yLabel": "185 378" - }, - "category": "Kukatpalle", - "y": 185378 - }, - { - "custom": { - "xLabel": "Katihar", - "yLabel": "154 367" - }, - "category": "Katihar", - "y": 154367 - }, - { - "custom": { - "xLabel": "Linhe", - "yLabel": "133 183" - }, - "category": "Linhe", - "y": 133183 - }, - { - "custom": { - "xLabel": "Ludhiana", - "yLabel": "1 042 740" - }, - "category": "Ludhiana", - "y": 1042740 - }, - { - "custom": { - "xLabel": "Juba", - "yLabel": "114 980" - }, - "category": "Juba", - "y": 114980 - }, - { - "custom": { - "xLabel": "Ikare", - "yLabel": "140 800" - }, - "category": "Ikare", - "y": 140800 - }, - { - "custom": { - "xLabel": "San Pedro Garza García", - "yLabel": "126 147" - }, - "category": "San Pedro Garza García", - "y": 126147 - }, - { - "custom": { - "xLabel": "Huangshi", - "yLabel": "457 601" - }, - "category": "Huangshi", - "y": 457601 - }, - { - "custom": { - "xLabel": "Punta Arenas", - "yLabel": "125 631" - }, - "category": "Punta Arenas", - "y": 125631 - }, - { - "custom": { - "xLabel": "Suhar", - "yLabel": "90 814" - }, - "category": "Suhar", - "y": 90814 - }, - { - "custom": { - "xLabel": "Escobar", - "yLabel": "116 675" - }, - "category": "Escobar", - "y": 116675 - }, - { - "custom": { - "xLabel": "Itabuna", - "yLabel": "182 148" - }, - "category": "Itabuna", - "y": 182148 - }, - { - "custom": { - "xLabel": "Wafangdian", - "yLabel": "251 733" - }, - "category": "Wafangdian", - "y": 251733 - }, - { - "custom": { - "xLabel": "Taegu", - "yLabel": "2 548 568" - }, - "category": "Taegu", - "y": 2548568 - }, - { - "custom": { - "xLabel": "Colatina", - "yLabel": "107 354" - }, - "category": "Colatina", - "y": 107354 - }, - { - "custom": { - "xLabel": "Jamnagar", - "yLabel": "341 637" - }, - "category": "Jamnagar", - "y": 341637 - }, - { - "custom": { - "xLabel": "Kumasi", - "yLabel": "385 192" - }, - "category": "Kumasi", - "y": 385192 - }, - { - "custom": { - "xLabel": "Pilibhit", - "yLabel": "106 605" - }, - "category": "Pilibhit", - "y": 106605 - }, - { - "custom": { - "xLabel": "Rafsanjan", - "yLabel": "98 300" - }, - "category": "Rafsanjan", - "y": 98300 - }, - { - "custom": { - "xLabel": "Abaetetuba", - "yLabel": "111 258" - }, - "category": "Abaetetuba", - "y": 111258 - }, - { - "custom": { - "xLabel": "Vladivostok", - "yLabel": "606 200" - }, - "category": "Vladivostok", - "y": 606200 - }, - { - "custom": { - "xLabel": "Monrovia", - "yLabel": "850 000" - }, - "category": "Monrovia", - "y": 850000 - }, - { - "custom": { - "xLabel": "Himeji", - "yLabel": "475 167" - }, - "category": "Himeji", - "y": 475167 - }, - { - "custom": { - "xLabel": "Fianarantsoa", - "yLabel": "99 005" - }, - "category": "Fianarantsoa", - "y": 99005 - }, - { - "custom": { - "xLabel": "Kitami", - "yLabel": "111 295" - }, - "category": "Kitami", - "y": 111295 - }, - { - "custom": { - "xLabel": "Ensenada", - "yLabel": "369 573" - }, - "category": "Ensenada", - "y": 369573 - }, - { - "custom": { - "xLabel": "Kemerovo", - "yLabel": "492 700" - }, - "category": "Kemerovo", - "y": 492700 - }, - { - "custom": { - "xLabel": "Mejicanos", - "yLabel": "138 800" - }, - "category": "Mejicanos", - "y": 138800 - }, - { - "custom": { - "xLabel": "Rzeszów", - "yLabel": "162 049" - }, - "category": "Rzeszów", - "y": 162049 - }, - { - "custom": { - "xLabel": "Cabanatuan", - "yLabel": "222 859" - }, - "category": "Cabanatuan", - "y": 222859 - }, - { - "custom": { - "xLabel": "Mufulira", - "yLabel": "123 900" - }, - "category": "Mufulira", - "y": 123900 - }, - { - "custom": { - "xLabel": "Tieli", - "yLabel": "265 683" - }, - "category": "Tieli", - "y": 265683 - }, - { - "custom": { - "xLabel": "Chula Vista", - "yLabel": "173 556" - }, - "category": "Chula Vista", - "y": 173556 - }, - { - "custom": { - "xLabel": "Pamplona [Iruña]", - "yLabel": "180 483" - }, - "category": "Pamplona [Iruña]", - "y": 180483 - }, - { - "custom": { - "xLabel": "Buenos Aires", - "yLabel": "2 982 146" - }, - "category": "Buenos Aires", - "y": 2982146 - }, - { - "custom": { - "xLabel": "Purnea (Purnia)", - "yLabel": "114 912" - }, - "category": "Purnea (Purnia)", - "y": 114912 - }, - { - "custom": { - "xLabel": "Woking/Byfleet", - "yLabel": "92 000" - }, - "category": "Woking/Byfleet", - "y": 92000 - }, - { - "custom": { - "xLabel": "Zlatoust", - "yLabel": "196 900" - }, - "category": "Zlatoust", - "y": 196900 - }, - { - "custom": { - "xLabel": "San Cristóbal de las Casas", - "yLabel": "132 317" - }, - "category": "San Cristóbal de las Casas", - "y": 132317 - }, - { - "custom": { - "xLabel": "Bergamo", - "yLabel": "117 837" - }, - "category": "Bergamo", - "y": 117837 - }, - { - "custom": { - "xLabel": "Sosnowiec", - "yLabel": "244 102" - }, - "category": "Sosnowiec", - "y": 244102 - }, - { - "custom": { - "xLabel": "São Carlos", - "yLabel": "187 122" - }, - "category": "São Carlos", - "y": 187122 - }, - { - "custom": { - "xLabel": "Quito", - "yLabel": "1 573 458" - }, - "category": "Quito", - "y": 1573458 - }, - { - "custom": { - "xLabel": "Tong Xian", - "yLabel": "97 168" - }, - "category": "Tong Xian", - "y": 97168 - }, - { - "custom": { - "xLabel": "Borisov", - "yLabel": "151 000" - }, - "category": "Borisov", - "y": 151000 - }, - { - "custom": { - "xLabel": "Delicias", - "yLabel": "116 132" - }, - "category": "Delicias", - "y": 116132 - }, - { - "custom": { - "xLabel": "Joetsu", - "yLabel": "133 505" - }, - "category": "Joetsu", - "y": 133505 - }, - { - "custom": { - "xLabel": "Neftekamsk", - "yLabel": "115 700" - }, - "category": "Neftekamsk", - "y": 115700 - }, - { - "custom": { - "xLabel": "Vantaa", - "yLabel": "178 471" - }, - "category": "Vantaa", - "y": 178471 - }, - { - "custom": { - "xLabel": "Islamabad", - "yLabel": "524 500" - }, - "category": "Islamabad", - "y": 524500 - }, - { - "custom": { - "xLabel": "Santa Rosa", - "yLabel": "185 633" - }, - "category": "Santa Rosa", - "y": 185633 - }, - { - "custom": { - "xLabel": "Iruma", - "yLabel": "145 922" - }, - "category": "Iruma", - "y": 145922 - }, - { - "custom": { - "xLabel": "Bago", - "yLabel": "141 721" - }, - "category": "Bago", - "y": 141721 - }, - { - "custom": { - "xLabel": "Nepean", - "yLabel": "115 100" - }, - "category": "Nepean", - "y": 115100 - }, - { - "custom": { - "xLabel": "Bologna", - "yLabel": "381 161" - }, - "category": "Bologna", - "y": 381161 - }, - { - "custom": { - "xLabel": "Pietermaritzburg", - "yLabel": "370 190" - }, - "category": "Pietermaritzburg", - "y": 370190 - }, - { - "custom": { - "xLabel": "Hsichuh", - "yLabel": "154 976" - }, - "category": "Hsichuh", - "y": 154976 - }, - { - "custom": { - "xLabel": "Gävle", - "yLabel": "90 742" - }, - "category": "Gävle", - "y": 90742 - }, - { - "custom": { - "xLabel": "Nizni Novgorod", - "yLabel": "1 357 000" - }, - "category": "Nizni Novgorod", - "y": 1357000 - }, - { - "custom": { - "xLabel": "Eldoret", - "yLabel": "111 882" - }, - "category": "Eldoret", - "y": 111882 - }, - { - "custom": { - "xLabel": "Bruxelles [Brussel]", - "yLabel": "133 859" - }, - "category": "Bruxelles [Brussel]", - "y": 133859 - }, - { - "custom": { - "xLabel": "Comodoro Rivadavia", - "yLabel": "124 104" - }, - "category": "Comodoro Rivadavia", - "y": 124104 - }, - { - "custom": { - "xLabel": "Saint Catharines", - "yLabel": "136 216" - }, - "category": "Saint Catharines", - "y": 136216 - }, - { - "custom": { - "xLabel": "Montevideo", - "yLabel": "1 236 000" - }, - "category": "Montevideo", - "y": 1236000 - }, - { - "custom": { - "xLabel": "Rouen", - "yLabel": "106 592" - }, - "category": "Rouen", - "y": 106592 - }, - { - "custom": { - "xLabel": "Muntinlupa", - "yLabel": "379 310" - }, - "category": "Muntinlupa", - "y": 379310 - }, - { - "custom": { - "xLabel": "Linyi", - "yLabel": "324 720" - }, - "category": "Linyi", - "y": 324720 - }, - { - "custom": { - "xLabel": "Västerås", - "yLabel": "126 328" - }, - "category": "Västerås", - "y": 126328 - }, - { - "custom": { - "xLabel": "Chaozhou", - "yLabel": "313 469" - }, - "category": "Chaozhou", - "y": 313469 - }, - { - "custom": { - "xLabel": "Habra", - "yLabel": "100 223" - }, - "category": "Habra", - "y": 100223 - }, - { - "custom": { - "xLabel": "Afyon", - "yLabel": "103 984" - }, - "category": "Afyon", - "y": 103984 - }, - { - "custom": { - "xLabel": "Timon", - "yLabel": "125 812" - }, - "category": "Timon", - "y": 125812 - }, - { - "custom": { - "xLabel": "Ulm", - "yLabel": "116 103" - }, - "category": "Ulm", - "y": 116103 - }, - { - "custom": { - "xLabel": "Mannheim", - "yLabel": "307 730" - }, - "category": "Mannheim", - "y": 307730 - }, - { - "custom": { - "xLabel": "Vitória de Santo Antão", - "yLabel": "113 595" - }, - "category": "Vitória de Santo Antão", - "y": 113595 - }, - { - "custom": { - "xLabel": "Guadalupe", - "yLabel": "668 780" - }, - "category": "Guadalupe", - "y": 668780 - }, - { - "custom": { - "xLabel": "Rasht", - "yLabel": "417 748" - }, - "category": "Rasht", - "y": 417748 - }, - { - "custom": { - "xLabel": "Achalpur", - "yLabel": "96 216" - }, - "category": "Achalpur", - "y": 96216 - }, - { - "custom": { - "xLabel": "Skikda", - "yLabel": "128 747" - }, - "category": "Skikda", - "y": 128747 - }, - { - "custom": { - "xLabel": "Dezhou", - "yLabel": "195 485" - }, - "category": "Dezhou", - "y": 195485 - }, - { - "custom": { - "xLabel": "Kirovograd", - "yLabel": "265 000" - }, - "category": "Kirovograd", - "y": 265000 - }, - { - "custom": { - "xLabel": "Suva", - "yLabel": "77 366" - }, - "category": "Suva", - "y": 77366 - }, - { - "custom": { - "xLabel": "Garden Grove", - "yLabel": "165 196" - }, - "category": "Garden Grove", - "y": 165196 - }, - { - "custom": { - "xLabel": "Mira Bhayandar", - "yLabel": "175 372" - }, - "category": "Mira Bhayandar", - "y": 175372 - }, - { - "custom": { - "xLabel": "Khan Yunis", - "yLabel": "123 175" - }, - "category": "Khan Yunis", - "y": 123175 - }, - { - "custom": { - "xLabel": "Engels", - "yLabel": "189 000" - }, - "category": "Engels", - "y": 189000 - }, - { - "custom": { - "xLabel": "Wuzhou", - "yLabel": "210 452" - }, - "category": "Wuzhou", - "y": 210452 - }, - { - "custom": { - "xLabel": "Leshan", - "yLabel": "341 128" - }, - "category": "Leshan", - "y": 341128 - }, - { - "custom": { - "xLabel": "Kelang", - "yLabel": "243 355" - }, - "category": "Kelang", - "y": 243355 - }, - { - "custom": { - "xLabel": "Kikwit", - "yLabel": "182 142" - }, - "category": "Kikwit", - "y": 182142 - }, - { - "custom": { - "xLabel": "Cajeme", - "yLabel": "355 679" - }, - "category": "Cajeme", - "y": 355679 - }, - { - "custom": { - "xLabel": "Gonder", - "yLabel": "112 249" - }, - "category": "Gonder", - "y": 112249 - }, - { - "custom": { - "xLabel": "Tomsk", - "yLabel": "482 100" - }, - "category": "Tomsk", - "y": 482100 - }, - { - "custom": { - "xLabel": "Hachioji", - "yLabel": "513 451" - }, - "category": "Hachioji", - "y": 513451 - }, - { - "custom": { - "xLabel": "Móstoles", - "yLabel": "195 351" - }, - "category": "Móstoles", - "y": 195351 - }, - { - "custom": { - "xLabel": "Shymkent", - "yLabel": "360 100" - }, - "category": "Shymkent", - "y": 360100 - }, - { - "custom": { - "xLabel": "Huddersfield", - "yLabel": "143 726" - }, - "category": "Huddersfield", - "y": 143726 - }, - { - "custom": { - "xLabel": "Kamensk-Uralski", - "yLabel": "190 600" - }, - "category": "Kamensk-Uralski", - "y": 190600 - }, - { - "custom": { - "xLabel": "Orizaba", - "yLabel": "118 488" - }, - "category": "Orizaba", - "y": 118488 - }, - { - "custom": { - "xLabel": "Leverkusen", - "yLabel": "160 841" - }, - "category": "Leverkusen", - "y": 160841 - }, - { - "custom": { - "xLabel": "Anshan", - "yLabel": "1 200 000" - }, - "category": "Anshan", - "y": 1200000 - }, - { - "custom": { - "xLabel": "Québec", - "yLabel": "167 264" - }, - "category": "Québec", - "y": 167264 - }, - { - "custom": { - "xLabel": "Neyagawa", - "yLabel": "257 315" - }, - "category": "Neyagawa", - "y": 257315 - }, - { - "custom": { - "xLabel": "Bhatpara", - "yLabel": "304 952" - }, - "category": "Bhatpara", - "y": 304952 - }, - { - "custom": { - "xLabel": "Caxias do Sul", - "yLabel": "349 581" - }, - "category": "Caxias do Sul", - "y": 349581 - }, - { - "custom": { - "xLabel": "Juzno-Sahalinsk", - "yLabel": "179 200" - }, - "category": "Juzno-Sahalinsk", - "y": 179200 - }, - { - "custom": { - "xLabel": "Zonguldak", - "yLabel": "111 542" - }, - "category": "Zonguldak", - "y": 111542 - }, - { - "custom": { - "xLabel": "Apatzingán", - "yLabel": "117 849" - }, - "category": "Apatzingán", - "y": 117849 - }, - { - "custom": { - "xLabel": "Secunderabad", - "yLabel": "167 461" - }, - "category": "Secunderabad", - "y": 167461 - }, - { - "custom": { - "xLabel": "Hachinohe", - "yLabel": "242 979" - }, - "category": "Hachinohe", - "y": 242979 - }, - { - "custom": { - "xLabel": "Huangshan", - "yLabel": "102 628" - }, - "category": "Huangshan", - "y": 102628 - }, - { - "custom": { - "xLabel": "Mojokerto", - "yLabel": "96 626" - }, - "category": "Mojokerto", - "y": 96626 - }, - { - "custom": { - "xLabel": "Lerdo", - "yLabel": "112 272" - }, - "category": "Lerdo", - "y": 112272 - }, - { - "custom": { - "xLabel": "Aqtau", - "yLabel": "143 400" - }, - "category": "Aqtau", - "y": 143400 - }, - { - "custom": { - "xLabel": "Hoya", - "yLabel": "100 313" - }, - "category": "Hoya", - "y": 100313 - }, - { - "custom": { - "xLabel": "Serravalle", - "yLabel": "4 802" - }, - "category": "Serravalle", - "y": 4802 - }, - { - "custom": { - "xLabel": "Guatire", - "yLabel": "109 121" - }, - "category": "Guatire", - "y": 109121 - }, - { - "custom": { - "xLabel": "Bandung", - "yLabel": "2 429 000" - }, - "category": "Bandung", - "y": 2429000 - }, - { - "custom": { - "xLabel": "Yonezawa", - "yLabel": "95 592" - }, - "category": "Yonezawa", - "y": 95592 - }, - { - "custom": { - "xLabel": "Hsinchu", - "yLabel": "361 958" - }, - "category": "Hsinchu", - "y": 361958 - }, - { - "custom": { - "xLabel": "Malasiqui", - "yLabel": "113 190" - }, - "category": "Malasiqui", - "y": 113190 - }, - { - "custom": { - "xLabel": "Belo Horizonte", - "yLabel": "2 139 125" - }, - "category": "Belo Horizonte", - "y": 2139125 - }, - { - "custom": { - "xLabel": "Barasat", - "yLabel": "107 365" - }, - "category": "Barasat", - "y": 107365 - }, - { - "custom": { - "xLabel": "North Shore", - "yLabel": "187 700" - }, - "category": "North Shore", - "y": 187700 - }, - { - "custom": { - "xLabel": "Antananarivo", - "yLabel": "675 669" - }, - "category": "Antananarivo", - "y": 675669 - }, - { - "custom": { - "xLabel": "Trieste", - "yLabel": "216 459" - }, - "category": "Trieste", - "y": 216459 - }, - { - "custom": { - "xLabel": "Sofija", - "yLabel": "1 122 302" - }, - "category": "Sofija", - "y": 1122302 - }, - { - "custom": { - "xLabel": "Shangrao", - "yLabel": "132 455" - }, - "category": "Shangrao", - "y": 132455 - }, - { - "custom": { - "xLabel": "Gjumri", - "yLabel": "211 700" - }, - "category": "Gjumri", - "y": 211700 - }, - { - "custom": { - "xLabel": "Slupsk", - "yLabel": "102 370" - }, - "category": "Slupsk", - "y": 102370 - }, - { - "custom": { - "xLabel": "Shanwei", - "yLabel": "107 847" - }, - "category": "Shanwei", - "y": 107847 - }, - { - "custom": { - "xLabel": "Poole", - "yLabel": "141 000" - }, - "category": "Poole", - "y": 141000 - }, - { - "custom": { - "xLabel": "Shashi", - "yLabel": "281 352" - }, - "category": "Shashi", - "y": 281352 - }, - { - "custom": { - "xLabel": "Maizuru", - "yLabel": "94 784" - }, - "category": "Maizuru", - "y": 94784 - }, - { - "custom": { - "xLabel": "Pelotas", - "yLabel": "315 415" - }, - "category": "Pelotas", - "y": 315415 - }, - { - "custom": { - "xLabel": "Miaoli", - "yLabel": "90 000" - }, - "category": "Miaoli", - "y": 90000 - }, - { - "custom": { - "xLabel": "Malayer", - "yLabel": "144 373" - }, - "category": "Malayer", - "y": 144373 - }, - { - "custom": { - "xLabel": "Hollywood", - "yLabel": "139 357" - }, - "category": "Hollywood", - "y": 139357 - }, - { - "custom": { - "xLabel": "Samarinda", - "yLabel": "399 175" - }, - "category": "Samarinda", - "y": 399175 - }, - { - "custom": { - "xLabel": "Cary", - "yLabel": "91 213" - }, - "category": "Cary", - "y": 91213 - }, - { - "custom": { - "xLabel": "Uhta", - "yLabel": "98 000" - }, - "category": "Uhta", - "y": 98000 - }, - { - "custom": { - "xLabel": "Hindupur", - "yLabel": "104 651" - }, - "category": "Hindupur", - "y": 104651 - }, - { - "custom": { - "xLabel": "Klaten", - "yLabel": "103 300" - }, - "category": "Klaten", - "y": 103300 - }, - { - "custom": { - "xLabel": "Beograd", - "yLabel": "1 204 000" - }, - "category": "Beograd", - "y": 1204000 - }, - { - "custom": { - "xLabel": "Plzen", - "yLabel": "166 759" - }, - "category": "Plzen", - "y": 166759 - }, - { - "custom": { - "xLabel": "Kulti-Barakar", - "yLabel": "108 518" - }, - "category": "Kulti-Barakar", - "y": 108518 - }, - { - "custom": { - "xLabel": "Ishinomaki", - "yLabel": "120 963" - }, - "category": "Ishinomaki", - "y": 120963 - }, - { - "custom": { - "xLabel": "Brakpan", - "yLabel": "171 363" - }, - "category": "Brakpan", - "y": 171363 - }, - { - "custom": { - "xLabel": "New York", - "yLabel": "8 008 278" - }, - "category": "New York", - "y": 8008278 - }, - { - "custom": { - "xLabel": "Hefei", - "yLabel": "1 369 100" - }, - "category": "Hefei", - "y": 1369100 - }, - { - "custom": { - "xLabel": "Araraquara", - "yLabel": "174 381" - }, - "category": "Araraquara", - "y": 174381 - }, - { - "custom": { - "xLabel": "Xingcheng", - "yLabel": "102 384" - }, - "category": "Xingcheng", - "y": 102384 - }, - { - "custom": { - "xLabel": "Las Vegas", - "yLabel": "478 434" - }, - "category": "Las Vegas", - "y": 478434 - }, - { - "custom": { - "xLabel": "Tabuk", - "yLabel": "292 600" - }, - "category": "Tabuk", - "y": 292600 - }, - { - "custom": { - "xLabel": "Chorzów", - "yLabel": "121 708" - }, - "category": "Chorzów", - "y": 121708 - }, - { - "custom": { - "xLabel": "Santa Marta", - "yLabel": "359 147" - }, - "category": "Santa Marta", - "y": 359147 - }, - { - "custom": { - "xLabel": "Rishon Le Ziyyon", - "yLabel": "188 200" - }, - "category": "Rishon Le Ziyyon", - "y": 188200 - }, - { - "custom": { - "xLabel": "Mosul", - "yLabel": "879 000" - }, - "category": "Mosul", - "y": 879000 - }, - { - "custom": { - "xLabel": "San Mateo", - "yLabel": "135 603" - }, - "category": "San Mateo", - "y": 135603 - }, - { - "custom": { - "xLabel": "Plymouth", - "yLabel": "253 000" - }, - "category": "Plymouth", - "y": 253000 - }, - { - "custom": { - "xLabel": "Yeotmal (Yavatmal)", - "yLabel": "108 578" - }, - "category": "Yeotmal (Yavatmal)", - "y": 108578 - }, - { - "custom": { - "xLabel": "Legazpi", - "yLabel": "157 010" - }, - "category": "Legazpi", - "y": 157010 - }, - { - "custom": { - "xLabel": "Ostrava", - "yLabel": "320 041" - }, - "category": "Ostrava", - "y": 320041 - }, - { - "custom": { - "xLabel": "Ciego de Ávila", - "yLabel": "98 505" - }, - "category": "Ciego de Ávila", - "y": 98505 - }, - { - "custom": { - "xLabel": "Cambridge", - "yLabel": "109 186" - }, - "category": "Cambridge", - "y": 109186 - }, - { - "custom": { - "xLabel": "Tehuacán", - "yLabel": "225 943" - }, - "category": "Tehuacán", - "y": 225943 - }, - { - "custom": { - "xLabel": "Kofu", - "yLabel": "199 753" - }, - "category": "Kofu", - "y": 199753 - }, - { - "custom": { - "xLabel": "Mandaluyong", - "yLabel": "278 474" - }, - "category": "Mandaluyong", - "y": 278474 - }, - { - "custom": { - "xLabel": "al-Hawamidiya", - "yLabel": "91 700" - }, - "category": "al-Hawamidiya", - "y": 91700 - }, - { - "custom": { - "xLabel": "Ciudad Bolívar", - "yLabel": "301 107" - }, - "category": "Ciudad Bolívar", - "y": 301107 - }, - { - "custom": { - "xLabel": "Larisa", - "yLabel": "113 090" - }, - "category": "Larisa", - "y": 113090 - }, - { - "custom": { - "xLabel": "Calabar", - "yLabel": "174 400" - }, - "category": "Calabar", - "y": 174400 - }, - { - "custom": { - "xLabel": "Ambattur", - "yLabel": "215 424" - }, - "category": "Ambattur", - "y": 215424 - }, - { - "custom": { - "xLabel": "Buffalo", - "yLabel": "292 648" - }, - "category": "Buffalo", - "y": 292648 - }, - { - "custom": { - "xLabel": "Leipzig", - "yLabel": "489 532" - }, - "category": "Leipzig", - "y": 489532 - }, - { - "custom": { - "xLabel": "Wendeng", - "yLabel": "133 910" - }, - "category": "Wendeng", - "y": 133910 - }, - { - "custom": { - "xLabel": "Bafoussam", - "yLabel": "131 000" - }, - "category": "Bafoussam", - "y": 131000 - }, - { - "custom": { - "xLabel": "Lázaro Cárdenas", - "yLabel": "170 878" - }, - "category": "Lázaro Cárdenas", - "y": 170878 - }, - { - "custom": { - "xLabel": "Monte-Carlo", - "yLabel": "13 154" - }, - "category": "Monte-Carlo", - "y": 13154 - }, - { - "custom": { - "xLabel": "Baliuag", - "yLabel": "119 675" - }, - "category": "Baliuag", - "y": 119675 - }, - { - "custom": { - "xLabel": "Hardwar (Haridwar)", - "yLabel": "147 305" - }, - "category": "Hardwar (Haridwar)", - "y": 147305 - }, - { - "custom": { - "xLabel": "Qaramay", - "yLabel": "197 602" - }, - "category": "Qaramay", - "y": 197602 - }, - { - "custom": { - "xLabel": "Wichita", - "yLabel": "344 284" - }, - "category": "Wichita", - "y": 344284 - }, - { - "custom": { - "xLabel": "Haikou", - "yLabel": "454 300" - }, - "category": "Haikou", - "y": 454300 - }, - { - "custom": { - "xLabel": "Port Said", - "yLabel": "469 533" - }, - "category": "Port Said", - "y": 469533 - }, - { - "custom": { - "xLabel": "Taganrog", - "yLabel": "284 400" - }, - "category": "Taganrog", - "y": 284400 - }, - { - "custom": { - "xLabel": "Saqqez", - "yLabel": "115 394" - }, - "category": "Saqqez", - "y": 115394 - }, - { - "custom": { - "xLabel": "Welkom", - "yLabel": "203 296" - }, - "category": "Welkom", - "y": 203296 - }, - { - "custom": { - "xLabel": "Santafé de Bogotá", - "yLabel": "6 260 862" - }, - "category": "Santafé de Bogotá", - "y": 6260862 - }, - { - "custom": { - "xLabel": "San Juan del Monte", - "yLabel": "117 680" - }, - "category": "San Juan del Monte", - "y": 117680 - }, - { - "custom": { - "xLabel": "Dhanbad", - "yLabel": "151 789" - }, - "category": "Dhanbad", - "y": 151789 - }, - { - "custom": { - "xLabel": "Halifax", - "yLabel": "113 910" - }, - "category": "Halifax", - "y": 113910 - }, - { - "custom": { - "xLabel": "Dehiwala", - "yLabel": "203 000" - }, - "category": "Dehiwala", - "y": 203000 - }, - { - "custom": { - "xLabel": "Istanbul", - "yLabel": "8 787 958" - }, - "category": "Istanbul", - "y": 8787958 - }, - { - "custom": { - "xLabel": "Cirebon", - "yLabel": "254 406" - }, - "category": "Cirebon", - "y": 254406 - }, - { - "custom": { - "xLabel": "Dudley", - "yLabel": "192 171" - }, - "category": "Dudley", - "y": 192171 - }, - { - "custom": { - "xLabel": "Porto", - "yLabel": "273 060" - }, - "category": "Porto", - "y": 273060 - }, - { - "custom": { - "xLabel": "Zürich", - "yLabel": "336 800" - }, - "category": "Zürich", - "y": 336800 - }, - { - "custom": { - "xLabel": "Dhule (Dhulia)", - "yLabel": "278 317" - }, - "category": "Dhule (Dhulia)", - "y": 278317 - }, - { - "custom": { - "xLabel": "Beau Bassin-Rose Hill", - "yLabel": "100 616" - }, - "category": "Beau Bassin-Rose Hill", - "y": 100616 - }, - { - "custom": { - "xLabel": "Herat", - "yLabel": "186 800" - }, - "category": "Herat", - "y": 186800 - }, - { - "custom": { - "xLabel": "Bismil", - "yLabel": "101 400" - }, - "category": "Bismil", - "y": 101400 - }, - { - "custom": { - "xLabel": "Rafah", - "yLabel": "92 020" - }, - "category": "Rafah", - "y": 92020 - }, - { - "custom": { - "xLabel": "Montpellier", - "yLabel": "225 392" - }, - "category": "Montpellier", - "y": 225392 - }, - { - "custom": { - "xLabel": "Barrancabermeja", - "yLabel": "178 020" - }, - "category": "Barrancabermeja", - "y": 178020 - }, - { - "custom": { - "xLabel": "Kirov", - "yLabel": "466 200" - }, - "category": "Kirov", - "y": 466200 - }, - { - "custom": { - "xLabel": "Gliwice", - "yLabel": "212 164" - }, - "category": "Gliwice", - "y": 212164 - }, - { - "custom": { - "xLabel": "Yushu", - "yLabel": "131 861" - }, - "category": "Yushu", - "y": 131861 - }, - { - "custom": { - "xLabel": "Palembang", - "yLabel": "1 222 764" - }, - "category": "Palembang", - "y": 1222764 - }, - { - "custom": { - "xLabel": "Walsall", - "yLabel": "174 739" - }, - "category": "Walsall", - "y": 174739 - }, - { - "custom": { - "xLabel": "Narashino", - "yLabel": "152 849" - }, - "category": "Narashino", - "y": 152849 - }, - { - "custom": { - "xLabel": "Namur", - "yLabel": "105 419" - }, - "category": "Namur", - "y": 105419 - }, - { - "custom": { - "xLabel": "Córdoba", - "yLabel": "176 952" - }, - "category": "Córdoba", - "y": 176952 - }, - { - "custom": { - "xLabel": "Khuzdar", - "yLabel": "93 100" - }, - "category": "Khuzdar", - "y": 93100 - }, - { - "custom": { - "xLabel": "Etawah", - "yLabel": "124 072" - }, - "category": "Etawah", - "y": 124072 - }, - { - "custom": { - "xLabel": "Tsuchiura", - "yLabel": "134 072" - }, - "category": "Tsuchiura", - "y": 134072 - }, - { - "custom": { - "xLabel": "Charleston", - "yLabel": "89 063" - }, - "category": "Charleston", - "y": 89063 - }, - { - "custom": { - "xLabel": "Rajshahi", - "yLabel": "294 056" - }, - "category": "Rajshahi", - "y": 294056 - }, - { - "custom": { - "xLabel": "Itagüí", - "yLabel": "228 985" - }, - "category": "Itagüí", - "y": 228985 - }, - { - "custom": { - "xLabel": "Angers", - "yLabel": "151 279" - }, - "category": "Angers", - "y": 151279 - }, - { - "custom": { - "xLabel": "Sogamoso", - "yLabel": "107 728" - }, - "category": "Sogamoso", - "y": 107728 - }, - { - "custom": { - "xLabel": "Quelimane", - "yLabel": "150 116" - }, - "category": "Quelimane", - "y": 150116 - }, - { - "custom": { - "xLabel": "Ech-Chleff (el-Asnam)", - "yLabel": "96 794" - }, - "category": "Ech-Chleff (el-Asnam)", - "y": 96794 - }, - { - "custom": { - "xLabel": "Santa Ana de Coro", - "yLabel": "185 766" - }, - "category": "Santa Ana de Coro", - "y": 185766 - }, - { - "custom": { - "xLabel": "Keelung (Chilung)", - "yLabel": "385 201" - }, - "category": "Keelung (Chilung)", - "y": 385201 - }, - { - "custom": { - "xLabel": "Baiyin", - "yLabel": "204 970" - }, - "category": "Baiyin", - "y": 204970 - }, - { - "custom": { - "xLabel": "Lysytšansk", - "yLabel": "116 000" - }, - "category": "Lysytšansk", - "y": 116000 - }, - { - "custom": { - "xLabel": "Daraga (Locsin)", - "yLabel": "101 031" - }, - "category": "Daraga (Locsin)", - "y": 101031 - }, - { - "custom": { - "xLabel": "Córdoba", - "yLabel": "1 157 507" - }, - "category": "Córdoba", - "y": 1157507 - }, - { - "custom": { - "xLabel": "Presidente Prudente", - "yLabel": "185 340" - }, - "category": "Presidente Prudente", - "y": 185340 - }, - { - "custom": { - "xLabel": "Kiryu", - "yLabel": "118 326" - }, - "category": "Kiryu", - "y": 118326 - }, - { - "custom": { - "xLabel": "Recife", - "yLabel": "1 378 087" - }, - "category": "Recife", - "y": 1378087 - }, - { - "custom": { - "xLabel": "Pegu (Bago)", - "yLabel": "190 900" - }, - "category": "Pegu (Bago)", - "y": 190900 - }, - { - "custom": { - "xLabel": "Kolhapur", - "yLabel": "406 370" - }, - "category": "Kolhapur", - "y": 406370 - }, - { - "custom": { - "xLabel": "Malabo", - "yLabel": "40 000" - }, - "category": "Malabo", - "y": 40000 - }, - { - "custom": { - "xLabel": "Fuxin", - "yLabel": "640 000" - }, - "category": "Fuxin", - "y": 640000 - }, - { - "custom": { - "xLabel": "Batam", - "yLabel": "91 871" - }, - "category": "Batam", - "y": 91871 - }, - { - "custom": { - "xLabel": "São Leopoldo", - "yLabel": "189 258" - }, - "category": "São Leopoldo", - "y": 189258 - }, - { - "custom": { - "xLabel": "Jinan", - "yLabel": "2 278 100" - }, - "category": "Jinan", - "y": 2278100 - }, - { - "custom": { - "xLabel": "Cixi", - "yLabel": "107 329" - }, - "category": "Cixi", - "y": 107329 - }, - { - "custom": { - "xLabel": "Karabük", - "yLabel": "118 285" - }, - "category": "Karabük", - "y": 118285 - }, - { - "custom": { - "xLabel": "Athenai", - "yLabel": "772 072" - }, - "category": "Athenai", - "y": 772072 - }, - { - "custom": { - "xLabel": "Zaoyang", - "yLabel": "162 198" - }, - "category": "Zaoyang", - "y": 162198 - }, - { - "custom": { - "xLabel": "Chiniot", - "yLabel": "169 300" - }, - "category": "Chiniot", - "y": 169300 - }, - { - "custom": { - "xLabel": "Catia La Mar", - "yLabel": "117 012" - }, - "category": "Catia La Mar", - "y": 117012 - }, - { - "custom": { - "xLabel": "Jincheng", - "yLabel": "136 396" - }, - "category": "Jincheng", - "y": 136396 - }, - { - "custom": { - "xLabel": "Smolensk", - "yLabel": "353 400" - }, - "category": "Smolensk", - "y": 353400 - }, - { - "custom": { - "xLabel": "Ksar el Kebir", - "yLabel": "107 065" - }, - "category": "Ksar el Kebir", - "y": 107065 - }, - { - "custom": { - "xLabel": "Tarlac", - "yLabel": "262 481" - }, - "category": "Tarlac", - "y": 262481 - }, - { - "custom": { - "xLabel": "Tel Aviv-Jaffa", - "yLabel": "348 100" - }, - "category": "Tel Aviv-Jaffa", - "y": 348100 - }, - { - "custom": { - "xLabel": "Managua", - "yLabel": "959 000" - }, - "category": "Managua", - "y": 959000 - }, - { - "custom": { - "xLabel": "Swindon", - "yLabel": "180 000" - }, - "category": "Swindon", - "y": 180000 - }, - { - "custom": { - "xLabel": "Guigang", - "yLabel": "114 025" - }, - "category": "Guigang", - "y": 114025 - }, - { - "custom": { - "xLabel": "Lalbahadur Nagar", - "yLabel": "155 500" - }, - "category": "Lalbahadur Nagar", - "y": 155500 - }, - { - "custom": { - "xLabel": "Santos", - "yLabel": "408 748" - }, - "category": "Santos", - "y": 408748 - }, - { - "custom": { - "xLabel": "Sydney", - "yLabel": "3 276 207" - }, - "category": "Sydney", - "y": 3276207 - }, - { - "custom": { - "xLabel": "Atsugi", - "yLabel": "212 407" - }, - "category": "Atsugi", - "y": 212407 - }, - { - "custom": { - "xLabel": "Liling", - "yLabel": "108 504" - }, - "category": "Liling", - "y": 108504 - }, - { - "custom": { - "xLabel": "Calicut (Kozhikode)", - "yLabel": "419 831" - }, - "category": "Calicut (Kozhikode)", - "y": 419831 - }, - { - "custom": { - "xLabel": "Sasaram", - "yLabel": "98 220" - }, - "category": "Sasaram", - "y": 98220 - }, - { - "custom": { - "xLabel": "Paraná", - "yLabel": "207 041" - }, - "category": "Paraná", - "y": 207041 - }, - { - "custom": { - "xLabel": "Hialeah", - "yLabel": "226 419" - }, - "category": "Hialeah", - "y": 226419 - }, - { - "custom": { - "xLabel": "Acuña", - "yLabel": "110 388" - }, - "category": "Acuña", - "y": 110388 - }, - { - "custom": { - "xLabel": "Kafr al-Dawwar", - "yLabel": "231 978" - }, - "category": "Kafr al-Dawwar", - "y": 231978 - }, - { - "custom": { - "xLabel": "Winnipeg", - "yLabel": "618 477" - }, - "category": "Winnipeg", - "y": 618477 - }, - { - "custom": { - "xLabel": "Atšinsk", - "yLabel": "121 600" - }, - "category": "Atšinsk", - "y": 121600 - }, - { - "custom": { - "xLabel": "Samsun", - "yLabel": "339 871" - }, - "category": "Samsun", - "y": 339871 - }, - { - "custom": { - "xLabel": "Ganzhou", - "yLabel": "220 129" - }, - "category": "Ganzhou", - "y": 220129 - }, - { - "custom": { - "xLabel": "Toledo", - "yLabel": "99 387" - }, - "category": "Toledo", - "y": 99387 - }, - { - "custom": { - "xLabel": "Lomé", - "yLabel": "375 000" - }, - "category": "Lomé", - "y": 375000 - }, - { - "custom": { - "xLabel": "Niiza", - "yLabel": "147 744" - }, - "category": "Niiza", - "y": 147744 - }, - { - "custom": { - "xLabel": "Juiz de Fora", - "yLabel": "450 288" - }, - "category": "Juiz de Fora", - "y": 450288 - }, - { - "custom": { - "xLabel": "Liyang", - "yLabel": "109 520" - }, - "category": "Liyang", - "y": 109520 - }, - { - "custom": { - "xLabel": "Pingdingshan", - "yLabel": "410 775" - }, - "category": "Pingdingshan", - "y": 410775 - }, - { - "custom": { - "xLabel": "Nürnberg", - "yLabel": "486 628" - }, - "category": "Nürnberg", - "y": 486628 - }, - { - "custom": { - "xLabel": "Kunpo", - "yLabel": "235 233" - }, - "category": "Kunpo", - "y": 235233 - }, - { - "custom": { - "xLabel": "Rio Verde", - "yLabel": "107 755" - }, - "category": "Rio Verde", - "y": 107755 - }, - { - "custom": { - "xLabel": "Puerto Vallarta", - "yLabel": "183 741" - }, - "category": "Puerto Vallarta", - "y": 183741 - }, - { - "custom": { - "xLabel": "al-Zawiya", - "yLabel": "89 338" - }, - "category": "al-Zawiya", - "y": 89338 - }, - { - "custom": { - "xLabel": "Salzgitter", - "yLabel": "112 934" - }, - "category": "Salzgitter", - "y": 112934 - }, - { - "custom": { - "xLabel": "Xi´an", - "yLabel": "2 761 400" - }, - "category": "Xi´an", - "y": 2761400 - }, - { - "custom": { - "xLabel": "Zigong", - "yLabel": "393 184" - }, - "category": "Zigong", - "y": 393184 - }, - { - "custom": { - "xLabel": "Koror", - "yLabel": "12 000" - }, - "category": "Koror", - "y": 12000 - }, - { - "custom": { - "xLabel": "Tucson", - "yLabel": "486 699" - }, - "category": "Tucson", - "y": 486699 - }, - { - "custom": { - "xLabel": "Bairiki", - "yLabel": "2 226" - }, - "category": "Bairiki", - "y": 2226 - }, - { - "custom": { - "xLabel": "Valencia", - "yLabel": "794 246" - }, - "category": "Valencia", - "y": 794246 - }, - { - "custom": { - "xLabel": "Barra Mansa", - "yLabel": "168 953" - }, - "category": "Barra Mansa", - "y": 168953 - }, - { - "custom": { - "xLabel": "Yinchuan", - "yLabel": "544 500" - }, - "category": "Yinchuan", - "y": 544500 - }, - { - "custom": { - "xLabel": "Florencia", - "yLabel": "108 574" - }, - "category": "Florencia", - "y": 108574 - }, - { - "custom": { - "xLabel": "Fuenlabrada", - "yLabel": "171 173" - }, - "category": "Fuenlabrada", - "y": 171173 - }, - { - "custom": { - "xLabel": "Oradea", - "yLabel": "222 239" - }, - "category": "Oradea", - "y": 222239 - }, - { - "custom": { - "xLabel": "Disuq", - "yLabel": "91 300" - }, - "category": "Disuq", - "y": 91300 - }, - { - "custom": { - "xLabel": "Cayenne", - "yLabel": "50 699" - }, - "category": "Cayenne", - "y": 50699 - }, - { - "custom": { - "xLabel": "Omiya", - "yLabel": "441 649" - }, - "category": "Omiya", - "y": 441649 - }, - { - "custom": { - "xLabel": "Pasadena", - "yLabel": "133 936" - }, - "category": "Pasadena", - "y": 133936 - }, - { - "custom": { - "xLabel": "Beirut", - "yLabel": "1 100 000" - }, - "category": "Beirut", - "y": 1100000 - }, - { - "custom": { - "xLabel": "Cuauhtémoc", - "yLabel": "124 279" - }, - "category": "Cuauhtémoc", - "y": 124279 - }, - { - "custom": { - "xLabel": "Haarlem", - "yLabel": "148 772" - }, - "category": "Haarlem", - "y": 148772 - }, - { - "custom": { - "xLabel": "Qinzhou", - "yLabel": "114 586" - }, - "category": "Qinzhou", - "y": 114586 - }, - { - "custom": { - "xLabel": "San Luis de la Paz", - "yLabel": "96 763" - }, - "category": "San Luis de la Paz", - "y": 96763 - }, - { - "custom": { - "xLabel": "Cariacica", - "yLabel": "319 033" - }, - "category": "Cariacica", - "y": 319033 - }, - { - "custom": { - "xLabel": "Huixquilucan", - "yLabel": "193 156" - }, - "category": "Huixquilucan", - "y": 193156 - }, - { - "custom": { - "xLabel": "Ankang", - "yLabel": "142 170" - }, - "category": "Ankang", - "y": 142170 - }, - { - "custom": { - "xLabel": "Yizheng", - "yLabel": "109 268" - }, - "category": "Yizheng", - "y": 109268 - }, - { - "custom": { - "xLabel": "Koriyama", - "yLabel": "330 335" - }, - "category": "Koriyama", - "y": 330335 - }, - { - "custom": { - "xLabel": "Tonghua", - "yLabel": "324 600" - }, - "category": "Tonghua", - "y": 324600 - }, - { - "custom": { - "xLabel": "Malatya", - "yLabel": "330 312" - }, - "category": "Malatya", - "y": 330312 - }, - { - "custom": { - "xLabel": "Yongju", - "yLabel": "131 097" - }, - "category": "Yongju", - "y": 131097 - }, - { - "custom": { - "xLabel": "Orléans", - "yLabel": "113 126" - }, - "category": "Orléans", - "y": 113126 - }, - { - "custom": { - "xLabel": "Tallinn", - "yLabel": "403 981" - }, - "category": "Tallinn", - "y": 403981 - }, - { - "custom": { - "xLabel": "Brindisi", - "yLabel": "93 454" - }, - "category": "Brindisi", - "y": 93454 - }, - { - "custom": { - "xLabel": "Sumaré", - "yLabel": "186 205" - }, - "category": "Sumaré", - "y": 186205 - }, - { - "custom": { - "xLabel": "Tajimi", - "yLabel": "103 171" - }, - "category": "Tajimi", - "y": 103171 - }, - { - "custom": { - "xLabel": "Raiganj", - "yLabel": "151 045" - }, - "category": "Raiganj", - "y": 151045 - }, - { - "custom": { - "xLabel": "Nikopol", - "yLabel": "149 000" - }, - "category": "Nikopol", - "y": 149000 - }, - { - "custom": { - "xLabel": "Zytomyr", - "yLabel": "297 000" - }, - "category": "Zytomyr", - "y": 297000 - }, - { - "custom": { - "xLabel": "Santiago Ixcuintla", - "yLabel": "95 311" - }, - "category": "Santiago Ixcuintla", - "y": 95311 - }, - { - "custom": { - "xLabel": "Cam Ranh", - "yLabel": "114 041" - }, - "category": "Cam Ranh", - "y": 114041 - }, - { - "custom": { - "xLabel": "Ljubertsy", - "yLabel": "163 900" - }, - "category": "Ljubertsy", - "y": 163900 - }, - { - "custom": { - "xLabel": "Bhimavaram", - "yLabel": "121 314" - }, - "category": "Bhimavaram", - "y": 121314 - }, - { - "custom": { - "xLabel": "Benin City", - "yLabel": "229 400" - }, - "category": "Benin City", - "y": 229400 - }, - { - "custom": { - "xLabel": "Heilbronn", - "yLabel": "119 526" - }, - "category": "Heilbronn", - "y": 119526 - }, - { - "custom": { - "xLabel": "Unayza", - "yLabel": "91 100" - }, - "category": "Unayza", - "y": 91100 - }, - { - "custom": { - "xLabel": "Tasikmalaya", - "yLabel": "179 800" - }, - "category": "Tasikmalaya", - "y": 179800 - }, - { - "custom": { - "xLabel": "Peoria", - "yLabel": "108 364" - }, - "category": "Peoria", - "y": 108364 - }, - { - "custom": { - "xLabel": "Sukabumi", - "yLabel": "125 766" - }, - "category": "Sukabumi", - "y": 125766 - }, - { - "custom": { - "xLabel": "Auckland", - "yLabel": "381 800" - }, - "category": "Auckland", - "y": 381800 - }, - { - "custom": { - "xLabel": "Sasebo", - "yLabel": "244 240" - }, - "category": "Sasebo", - "y": 244240 - }, - { - "custom": { - "xLabel": "Sanliurfa", - "yLabel": "405 905" - }, - "category": "Sanliurfa", - "y": 405905 - }, - { - "custom": { - "xLabel": "Sanandaj", - "yLabel": "277 808" - }, - "category": "Sanandaj", - "y": 277808 - }, - { - "custom": { - "xLabel": "East Los Angeles", - "yLabel": "126 379" - }, - "category": "East Los Angeles", - "y": 126379 - }, - { - "custom": { - "xLabel": "Tengzhou", - "yLabel": "315 083" - }, - "category": "Tengzhou", - "y": 315083 - }, - { - "custom": { - "xLabel": "Botosani", - "yLabel": "128 730" - }, - "category": "Botosani", - "y": 128730 - }, - { - "custom": { - "xLabel": "Guelph", - "yLabel": "103 593" - }, - "category": "Guelph", - "y": 103593 - }, - { - "custom": { - "xLabel": "Bissau", - "yLabel": "241 000" - }, - "category": "Bissau", - "y": 241000 - }, - { - "custom": { - "xLabel": "Tulsa", - "yLabel": "393 049" - }, - "category": "Tulsa", - "y": 393049 - }, - { - "custom": { - "xLabel": "Pinetown", - "yLabel": "378 810" - }, - "category": "Pinetown", - "y": 378810 - }, - { - "custom": { - "xLabel": "Gusau", - "yLabel": "158 000" - }, - "category": "Gusau", - "y": 158000 - }, - { - "custom": { - "xLabel": "Quetta", - "yLabel": "560 307" - }, - "category": "Quetta", - "y": 560307 - }, - { - "custom": { - "xLabel": "Bhilai", - "yLabel": "386 159" - }, - "category": "Bhilai", - "y": 386159 - }, - { - "custom": { - "xLabel": "Juazeiro do Norte", - "yLabel": "199 636" - }, - "category": "Juazeiro do Norte", - "y": 199636 - }, - { - "custom": { - "xLabel": "Suzuka", - "yLabel": "184 061" - }, - "category": "Suzuka", - "y": 184061 - }, - { - "custom": { - "xLabel": "Kecskemét", - "yLabel": "105 606" - }, - "category": "Kecskemét", - "y": 105606 - }, - { - "custom": { - "xLabel": "Jodhpur", - "yLabel": "666 279" - }, - "category": "Jodhpur", - "y": 666279 - }, - { - "custom": { - "xLabel": "Duyun", - "yLabel": "132 971" - }, - "category": "Duyun", - "y": 132971 - }, - { - "custom": { - "xLabel": "Korla", - "yLabel": "159 344" - }, - "category": "Korla", - "y": 159344 - }, - { - "custom": { - "xLabel": "Viña del Mar", - "yLabel": "312 493" - }, - "category": "Viña del Mar", - "y": 312493 - }, - { - "custom": { - "xLabel": "Quzhou", - "yLabel": "112 373" - }, - "category": "Quzhou", - "y": 112373 - }, - { - "custom": { - "xLabel": "Budaun", - "yLabel": "116 695" - }, - "category": "Budaun", - "y": 116695 - }, - { - "custom": { - "xLabel": "Nablus", - "yLabel": "100 231" - }, - "category": "Nablus", - "y": 100231 - }, - { - "custom": { - "xLabel": "Chennai (Madras)", - "yLabel": "3 841 396" - }, - "category": "Chennai (Madras)", - "y": 3841396 - }, - { - "custom": { - "xLabel": "Bouaké", - "yLabel": "329 850" - }, - "category": "Bouaké", - "y": 329850 - }, - { - "custom": { - "xLabel": "Sahiwal", - "yLabel": "207 388" - }, - "category": "Sahiwal", - "y": 207388 - }, - { - "custom": { - "xLabel": "Zitácuaro", - "yLabel": "137 970" - }, - "category": "Zitácuaro", - "y": 137970 - }, - { - "custom": { - "xLabel": "Anantapur", - "yLabel": "174 924" - }, - "category": "Anantapur", - "y": 174924 - }, - { - "custom": { - "xLabel": "Iserlohn", - "yLabel": "99 474" - }, - "category": "Iserlohn", - "y": 99474 - }, - { - "custom": { - "xLabel": "Punto Fijo", - "yLabel": "167 215" - }, - "category": "Punto Fijo", - "y": 167215 - }, - { - "custom": { - "xLabel": "Torre del Greco", - "yLabel": "94 505" - }, - "category": "Torre del Greco", - "y": 94505 - }, - { - "custom": { - "xLabel": "Fakaofo", - "yLabel": "300" - }, - "category": "Fakaofo", - "y": 300 - }, - { - "custom": { - "xLabel": "Basel", - "yLabel": "166 700" - }, - "category": "Basel", - "y": 166700 - }, - { - "custom": { - "xLabel": "Omdurman", - "yLabel": "1 271 403" - }, - "category": "Omdurman", - "y": 1271403 - }, - { - "custom": { - "xLabel": "Middlesbrough", - "yLabel": "145 000" - }, - "category": "Middlesbrough", - "y": 145000 - }, - { - "custom": { - "xLabel": "Oklahoma City", - "yLabel": "506 132" - }, - "category": "Oklahoma City", - "y": 506132 - }, - { - "custom": { - "xLabel": "Luohe", - "yLabel": "126 438" - }, - "category": "Luohe", - "y": 126438 - }, - { - "custom": { - "xLabel": "Gothenburg [Göteborg]", - "yLabel": "466 990" - }, - "category": "Gothenburg [Göteborg]", - "y": 466990 - }, - { - "custom": { - "xLabel": "Cizah", - "yLabel": "124 800" - }, - "category": "Cizah", - "y": 124800 - }, - { - "custom": { - "xLabel": "Lalitapur", - "yLabel": "145 847" - }, - "category": "Lalitapur", - "y": 145847 - }, - { - "custom": { - "xLabel": "Haining", - "yLabel": "100 478" - }, - "category": "Haining", - "y": 100478 - }, - { - "custom": { - "xLabel": "Soka", - "yLabel": "222 768" - }, - "category": "Soka", - "y": 222768 - }, - { - "custom": { - "xLabel": "Puškin", - "yLabel": "92 900" - }, - "category": "Puškin", - "y": 92900 - }, - { - "custom": { - "xLabel": "Qingdao", - "yLabel": "2 596 000" - }, - "category": "Qingdao", - "y": 2596000 - }, - { - "custom": { - "xLabel": "Guntur", - "yLabel": "471 051" - }, - "category": "Guntur", - "y": 471051 - }, - { - "custom": { - "xLabel": "Fès", - "yLabel": "541 162" - }, - "category": "Fès", - "y": 541162 - }, - { - "custom": { - "xLabel": "Seattle", - "yLabel": "563 374" - }, - "category": "Seattle", - "y": 563374 - }, - { - "custom": { - "xLabel": "Khandwa", - "yLabel": "145 133" - }, - "category": "Khandwa", - "y": 145133 - }, - { - "custom": { - "xLabel": "Hampton", - "yLabel": "146 437" - }, - "category": "Hampton", - "y": 146437 - }, - { - "custom": { - "xLabel": "Higashihiroshima", - "yLabel": "119 166" - }, - "category": "Higashihiroshima", - "y": 119166 - }, - { - "custom": { - "xLabel": "Kaolack", - "yLabel": "199 000" - }, - "category": "Kaolack", - "y": 199000 - }, - { - "custom": { - "xLabel": "Taraz", - "yLabel": "330 100" - }, - "category": "Taraz", - "y": 330100 - }, - { - "custom": { - "xLabel": "Qalyub", - "yLabel": "97 200" - }, - "category": "Qalyub", - "y": 97200 - }, - { - "custom": { - "xLabel": "Volta Redonda", - "yLabel": "240 315" - }, - "category": "Volta Redonda", - "y": 240315 - }, - { - "custom": { - "xLabel": "Siping", - "yLabel": "317 223" - }, - "category": "Siping", - "y": 317223 - }, - { - "custom": { - "xLabel": "Nezahualcóyotl", - "yLabel": "1 224 924" - }, - "category": "Nezahualcóyotl", - "y": 1224924 - }, - { - "custom": { - "xLabel": "Namwon", - "yLabel": "103 544" - }, - "category": "Namwon", - "y": 103544 - }, - { - "custom": { - "xLabel": "Pánuco", - "yLabel": "90 551" - }, - "category": "Pánuco", - "y": 90551 - }, - { - "custom": { - "xLabel": "Yazd", - "yLabel": "326 776" - }, - "category": "Yazd", - "y": 326776 - }, - { - "custom": { - "xLabel": "Puerto Cabello", - "yLabel": "187 722" - }, - "category": "Puerto Cabello", - "y": 187722 - }, - { - "custom": { - "xLabel": "Oldham", - "yLabel": "103 931" - }, - "category": "Oldham", - "y": 103931 - }, - { - "custom": { - "xLabel": "Miyazaki", - "yLabel": "303 784" - }, - "category": "Miyazaki", - "y": 303784 - }, - { - "custom": { - "xLabel": "Ust-Ilimsk", - "yLabel": "105 200" - }, - "category": "Ust-Ilimsk", - "y": 105200 - }, - { - "custom": { - "xLabel": "Petrolina", - "yLabel": "210 540" - }, - "category": "Petrolina", - "y": 210540 - }, - { - "custom": { - "xLabel": "Harbin", - "yLabel": "4 289 800" - }, - "category": "Harbin", - "y": 4289800 - }, - { - "custom": { - "xLabel": "Sariaya", - "yLabel": "114 568" - }, - "category": "Sariaya", - "y": 114568 - }, - { - "custom": { - "xLabel": "Xinyu", - "yLabel": "173 524" - }, - "category": "Xinyu", - "y": 173524 - }, - { - "custom": { - "xLabel": "Abbotsford", - "yLabel": "105 403" - }, - "category": "Abbotsford", - "y": 105403 - }, - { - "custom": { - "xLabel": "Torun", - "yLabel": "206 158" - }, - "category": "Torun", - "y": 206158 - }, - { - "custom": { - "xLabel": "Tete", - "yLabel": "101 984" - }, - "category": "Tete", - "y": 101984 - }, - { - "custom": { - "xLabel": "Bharuch (Broach)", - "yLabel": "133 102" - }, - "category": "Bharuch (Broach)", - "y": 133102 - }, - { - "custom": { - "xLabel": "Saint-Denis", - "yLabel": "131 480" - }, - "category": "Saint-Denis", - "y": 131480 - }, - { - "custom": { - "xLabel": "Tšernigiv", - "yLabel": "313 000" - }, - "category": "Tšernigiv", - "y": 313000 - }, - { - "custom": { - "xLabel": "Changde", - "yLabel": "301 276" - }, - "category": "Changde", - "y": 301276 - }, - { - "custom": { - "xLabel": "Modena", - "yLabel": "176 022" - }, - "category": "Modena", - "y": 176022 - }, - { - "custom": { - "xLabel": "Tebing Tinggi", - "yLabel": "129 300" - }, - "category": "Tebing Tinggi", - "y": 129300 - }, - { - "custom": { - "xLabel": "Sandy", - "yLabel": "101 853" - }, - "category": "Sandy", - "y": 101853 - }, - { - "custom": { - "xLabel": "Cibinong", - "yLabel": "101 300" - }, - "category": "Cibinong", - "y": 101300 - }, - { - "custom": { - "xLabel": "Valle de la Pascua", - "yLabel": "95 927" - }, - "category": "Valle de la Pascua", - "y": 95927 - }, - { - "custom": { - "xLabel": "Ise-Ekiti", - "yLabel": "103 400" - }, - "category": "Ise-Ekiti", - "y": 103400 - }, - { - "custom": { - "xLabel": "Montreuil", - "yLabel": "90 674" - }, - "category": "Montreuil", - "y": 90674 - }, - { - "custom": { - "xLabel": "Toyohashi", - "yLabel": "360 066" - }, - "category": "Toyohashi", - "y": 360066 - }, - { - "custom": { - "xLabel": "Gary", - "yLabel": "102 746" - }, - "category": "Gary", - "y": 102746 - }, - { - "custom": { - "xLabel": "Waitakere", - "yLabel": "170 600" - }, - "category": "Waitakere", - "y": 170600 - }, - { - "custom": { - "xLabel": "Fargona", - "yLabel": "180 500" - }, - "category": "Fargona", - "y": 180500 - }, - { - "custom": { - "xLabel": "Uvira", - "yLabel": "115 590" - }, - "category": "Uvira", - "y": 115590 - }, - { - "custom": { - "xLabel": "Laiyang", - "yLabel": "137 080" - }, - "category": "Laiyang", - "y": 137080 - }, - { - "custom": { - "xLabel": "Nagar Coil", - "yLabel": "190 084" - }, - "category": "Nagar Coil", - "y": 190084 - }, - { - "custom": { - "xLabel": "Ara´ar", - "yLabel": "108 100" - }, - "category": "Ara´ar", - "y": 108100 - }, - { - "custom": { - "xLabel": "al-Mubarraz", - "yLabel": "219 100" - }, - "category": "al-Mubarraz", - "y": 219100 - }, - { - "custom": { - "xLabel": "Šahty", - "yLabel": "221 800" - }, - "category": "Šahty", - "y": 221800 - }, - { - "custom": { - "xLabel": "Manta", - "yLabel": "164 739" - }, - "category": "Manta", - "y": 164739 - }, - { - "custom": { - "xLabel": "Seremban", - "yLabel": "182 869" - }, - "category": "Seremban", - "y": 182869 - }, - { - "custom": { - "xLabel": "Chhindwara", - "yLabel": "93 731" - }, - "category": "Chhindwara", - "y": 93731 - }, - { - "custom": { - "xLabel": "Arapiraca", - "yLabel": "178 988" - }, - "category": "Arapiraca", - "y": 178988 - }, - { - "custom": { - "xLabel": "Caen", - "yLabel": "113 987" - }, - "category": "Caen", - "y": 113987 - }, - { - "custom": { - "xLabel": "Novopolotsk", - "yLabel": "106 000" - }, - "category": "Novopolotsk", - "y": 106000 - }, - { - "custom": { - "xLabel": "Esteban Echeverría", - "yLabel": "235 760" - }, - "category": "Esteban Echeverría", - "y": 235760 - }, - { - "custom": { - "xLabel": "Niznevartovsk", - "yLabel": "233 900" - }, - "category": "Niznevartovsk", - "y": 233900 - }, - { - "custom": { - "xLabel": "Sutton Coldfield", - "yLabel": "106 001" - }, - "category": "Sutton Coldfield", - "y": 106001 - }, - { - "custom": { - "xLabel": "Depok", - "yLabel": "106 800" - }, - "category": "Depok", - "y": 106800 - }, - { - "custom": { - "xLabel": "Chang-won", - "yLabel": "481 694" - }, - "category": "Chang-won", - "y": 481694 - }, - { - "custom": { - "xLabel": "Munich [München]", - "yLabel": "1 194 560" - }, - "category": "Munich [München]", - "y": 1194560 - }, - { - "custom": { - "xLabel": "Tšerkasy", - "yLabel": "309 000" - }, - "category": "Tšerkasy", - "y": 309000 - }, - { - "custom": { - "xLabel": "Nanchong", - "yLabel": "180 273" - }, - "category": "Nanchong", - "y": 180273 - }, - { - "custom": { - "xLabel": "Biskra", - "yLabel": "128 281" - }, - "category": "Biskra", - "y": 128281 - }, - { - "custom": { - "xLabel": "Cotabato", - "yLabel": "163 849" - }, - "category": "Cotabato", - "y": 163849 - }, - { - "custom": { - "xLabel": "Cainta", - "yLabel": "242 511" - }, - "category": "Cainta", - "y": 242511 - }, - { - "custom": { - "xLabel": "Velikije Luki", - "yLabel": "116 300" - }, - "category": "Velikije Luki", - "y": 116300 - }, - { - "custom": { - "xLabel": "Hue", - "yLabel": "219 149" - }, - "category": "Hue", - "y": 219149 - }, - { - "custom": { - "xLabel": "Esslingen am Neckar", - "yLabel": "89 667" - }, - "category": "Esslingen am Neckar", - "y": 89667 - }, - { - "custom": { - "xLabel": "Toyokawa", - "yLabel": "115 781" - }, - "category": "Toyokawa", - "y": 115781 - }, - { - "custom": { - "xLabel": "Raleigh", - "yLabel": "276 093" - }, - "category": "Raleigh", - "y": 276093 - }, - { - "custom": { - "xLabel": "Padang Sidempuan", - "yLabel": "91 200" - }, - "category": "Padang Sidempuan", - "y": 91200 - }, - { - "custom": { - "xLabel": "Chungju", - "yLabel": "205 206" - }, - "category": "Chungju", - "y": 205206 - }, - { - "custom": { - "xLabel": "Bhir (Bid)", - "yLabel": "112 434" - }, - "category": "Bhir (Bid)", - "y": 112434 - }, - { - "custom": { - "xLabel": "Terrassa", - "yLabel": "168 695" - }, - "category": "Terrassa", - "y": 168695 - }, - { - "custom": { - "xLabel": "Valladolid", - "yLabel": "319 998" - }, - "category": "Valladolid", - "y": 319998 - }, - { - "custom": { - "xLabel": "Andorra la Vella", - "yLabel": "21 189" - }, - "category": "Andorra la Vella", - "y": 21189 - }, - { - "custom": { - "xLabel": "Shihezi", - "yLabel": "299 676" - }, - "category": "Shihezi", - "y": 299676 - }, - { - "custom": { - "xLabel": "Fengshan", - "yLabel": "318 562" - }, - "category": "Fengshan", - "y": 318562 - }, - { - "custom": { - "xLabel": "Lobito", - "yLabel": "130 000" - }, - "category": "Lobito", - "y": 130000 - }, - { - "custom": { - "xLabel": "Tsuyama", - "yLabel": "91 170" - }, - "category": "Tsuyama", - "y": 91170 - }, - { - "custom": { - "xLabel": "Hidalgo", - "yLabel": "106 198" - }, - "category": "Hidalgo", - "y": 106198 - }, - { - "custom": { - "xLabel": "Netanya", - "yLabel": "154 900" - }, - "category": "Netanya", - "y": 154900 - }, - { - "custom": { - "xLabel": "Roseau", - "yLabel": "16 243" - }, - "category": "Roseau", - "y": 16243 - }, - { - "custom": { - "xLabel": "Chaoyang", - "yLabel": "222 394" - }, - "category": "Chaoyang", - "y": 222394 - }, - { - "custom": { - "xLabel": "Gloucester", - "yLabel": "107 000" - }, - "category": "Gloucester", - "y": 107000 - }, - { - "custom": { - "xLabel": "Jersey City", - "yLabel": "240 055" - }, - "category": "Jersey City", - "y": 240055 - }, - { - "custom": { - "xLabel": "Nîmes", - "yLabel": "133 424" - }, - "category": "Nîmes", - "y": 133424 - }, - { - "custom": { - "xLabel": "Cambridge", - "yLabel": "121 000" - }, - "category": "Cambridge", - "y": 121000 - }, - { - "custom": { - "xLabel": "Tungi", - "yLabel": "168 702" - }, - "category": "Tungi", - "y": 168702 - }, - { - "custom": { - "xLabel": "Kallithea", - "yLabel": "114 233" - }, - "category": "Kallithea", - "y": 114233 - }, - { - "custom": { - "xLabel": "Saga", - "yLabel": "170 034" - }, - "category": "Saga", - "y": 170034 - }, - { - "custom": { - "xLabel": "Buon Ma Thuot", - "yLabel": "97 044" - }, - "category": "Buon Ma Thuot", - "y": 97044 - }, - { - "custom": { - "xLabel": "Guarenas", - "yLabel": "165 889" - }, - "category": "Guarenas", - "y": 165889 - }, - { - "custom": { - "xLabel": "Antipolo", - "yLabel": "470 866" - }, - "category": "Antipolo", - "y": 470866 - }, - { - "custom": { - "xLabel": "Toronto", - "yLabel": "688 275" - }, - "category": "Toronto", - "y": 688275 - }, - { - "custom": { - "xLabel": "Offenbach am Main", - "yLabel": "116 627" - }, - "category": "Offenbach am Main", - "y": 116627 - }, - { - "custom": { - "xLabel": "Dayr al-Zawr", - "yLabel": "140 459" - }, - "category": "Dayr al-Zawr", - "y": 140459 - }, - { - "custom": { - "xLabel": "Daxian", - "yLabel": "188 101" - }, - "category": "Daxian", - "y": 188101 - }, - { - "custom": { - "xLabel": "Jena", - "yLabel": "99 779" - }, - "category": "Jena", - "y": 99779 - }, - { - "custom": { - "xLabel": "Itaboraí", - "yLabel": "173 977" - }, - "category": "Itaboraí", - "y": 173977 - }, - { - "custom": { - "xLabel": "Ikorodu", - "yLabel": "184 900" - }, - "category": "Ikorodu", - "y": 184900 - }, - { - "custom": { - "xLabel": "Dongwan", - "yLabel": "308 669" - }, - "category": "Dongwan", - "y": 308669 - }, - { - "custom": { - "xLabel": "Sagay", - "yLabel": "129 765" - }, - "category": "Sagay", - "y": 129765 - }, - { - "custom": { - "xLabel": "Dublin", - "yLabel": "481 854" - }, - "category": "Dublin", - "y": 481854 - }, - { - "custom": { - "xLabel": "Ejigbo", - "yLabel": "105 900" - }, - "category": "Ejigbo", - "y": 105900 - }, - { - "custom": { - "xLabel": "Tver", - "yLabel": "454 900" - }, - "category": "Tver", - "y": 454900 - }, - { - "custom": { - "xLabel": "Bettiah", - "yLabel": "92 583" - }, - "category": "Bettiah", - "y": 92583 - }, - { - "custom": { - "xLabel": "al-Nasiriya", - "yLabel": "265 937" - }, - "category": "al-Nasiriya", - "y": 265937 - }, - { - "custom": { - "xLabel": "Ma´anshan", - "yLabel": "305 421" - }, - "category": "Ma´anshan", - "y": 305421 - }, - { - "custom": { - "xLabel": "Randburg", - "yLabel": "341 288" - }, - "category": "Randburg", - "y": 341288 - }, - { - "custom": { - "xLabel": "Jaén", - "yLabel": "109 247" - }, - "category": "Jaén", - "y": 109247 - }, - { - "custom": { - "xLabel": "Dinajpur", - "yLabel": "127 815" - }, - "category": "Dinajpur", - "y": 127815 - }, - { - "custom": { - "xLabel": "Shubra al-Khayma", - "yLabel": "870 716" - }, - "category": "Shubra al-Khayma", - "y": 870716 - }, - { - "custom": { - "xLabel": "Ambala Sadar", - "yLabel": "90 712" - }, - "category": "Ambala Sadar", - "y": 90712 - }, - { - "custom": { - "xLabel": "Tripoli", - "yLabel": "240 000" - }, - "category": "Tripoli", - "y": 240000 - }, - { - "custom": { - "xLabel": "Mississauga", - "yLabel": "608 072" - }, - "category": "Mississauga", - "y": 608072 - }, - { - "custom": { - "xLabel": "Kyongju", - "yLabel": "272 968" - }, - "category": "Kyongju", - "y": 272968 - }, - { - "custom": { - "xLabel": "Richmond Hill", - "yLabel": "116 428" - }, - "category": "Richmond Hill", - "y": 116428 - }, - { - "custom": { - "xLabel": "Foshan", - "yLabel": "303 160" - }, - "category": "Foshan", - "y": 303160 - }, - { - "custom": { - "xLabel": "Dakar", - "yLabel": "785 071" - }, - "category": "Dakar", - "y": 785071 - }, - { - "custom": { - "xLabel": "Changchun", - "yLabel": "2 812 000" - }, - "category": "Changchun", - "y": 2812000 - }, - { - "custom": { - "xLabel": "Cubatão", - "yLabel": "102 372" - }, - "category": "Cubatão", - "y": 102372 - }, - { - "custom": { - "xLabel": "Uiwang", - "yLabel": "108 788" - }, - "category": "Uiwang", - "y": 108788 - }, - { - "custom": { - "xLabel": "Cadiz", - "yLabel": "141 954" - }, - "category": "Cadiz", - "y": 141954 - }, - { - "custom": { - "xLabel": "Novouralsk", - "yLabel": "93 300" - }, - "category": "Novouralsk", - "y": 93300 - }, - { - "custom": { - "xLabel": "Jessore", - "yLabel": "139 710" - }, - "category": "Jessore", - "y": 139710 - }, - { - "custom": { - "xLabel": "Thiès", - "yLabel": "248 000" - }, - "category": "Thiès", - "y": 248000 - }, - { - "custom": { - "xLabel": "Cape Breton", - "yLabel": "114 733" - }, - "category": "Cape Breton", - "y": 114733 - }, - { - "custom": { - "xLabel": "Anand", - "yLabel": "110 266" - }, - "category": "Anand", - "y": 110266 - }, - { - "custom": { - "xLabel": "Olongapo", - "yLabel": "194 260" - }, - "category": "Olongapo", - "y": 194260 - }, - { - "custom": { - "xLabel": "Tai´an", - "yLabel": "350 696" - }, - "category": "Tai´an", - "y": 350696 - }, - { - "custom": { - "xLabel": "Piura", - "yLabel": "325 000" - }, - "category": "Piura", - "y": 325000 - }, - { - "custom": { - "xLabel": "Krasnyi Lutš", - "yLabel": "101 000" - }, - "category": "Krasnyi Lutš", - "y": 101000 - }, - { - "custom": { - "xLabel": "Kueishan", - "yLabel": "112 195" - }, - "category": "Kueishan", - "y": 112195 - }, - { - "custom": { - "xLabel": "Alberton", - "yLabel": "410 102" - }, - "category": "Alberton", - "y": 410102 - }, - { - "custom": { - "xLabel": "Effon-Alaiye", - "yLabel": "153 100" - }, - "category": "Effon-Alaiye", - "y": 153100 - }, - { - "custom": { - "xLabel": "Siegen", - "yLabel": "109 225" - }, - "category": "Siegen", - "y": 109225 - }, - { - "custom": { - "xLabel": "Oyama", - "yLabel": "152 820" - }, - "category": "Oyama", - "y": 152820 - }, - { - "custom": { - "xLabel": "Freiburg im Breisgau", - "yLabel": "202 455" - }, - "category": "Freiburg im Breisgau", - "y": 202455 - }, - { - "custom": { - "xLabel": "Bikaner", - "yLabel": "416 289" - }, - "category": "Bikaner", - "y": 416289 - }, - { - "custom": { - "xLabel": "Ahmadnagar", - "yLabel": "181 339" - }, - "category": "Ahmadnagar", - "y": 181339 - }, - { - "custom": { - "xLabel": "Tiefa", - "yLabel": "131 807" - }, - "category": "Tiefa", - "y": 131807 - }, - { - "custom": { - "xLabel": "Lauro de Freitas", - "yLabel": "109 236" - }, - "category": "Lauro de Freitas", - "y": 109236 - }, - { - "custom": { - "xLabel": "Yuanlin", - "yLabel": "126 402" - }, - "category": "Yuanlin", - "y": 126402 - }, - { - "custom": { - "xLabel": "Gaya", - "yLabel": "291 675" - }, - "category": "Gaya", - "y": 291675 - }, - { - "custom": { - "xLabel": "Topeka", - "yLabel": "122 377" - }, - "category": "Topeka", - "y": 122377 - }, - { - "custom": { - "xLabel": "Herakleion", - "yLabel": "116 178" - }, - "category": "Herakleion", - "y": 116178 - }, - { - "custom": { - "xLabel": "Novara", - "yLabel": "102 037" - }, - "category": "Novara", - "y": 102037 - }, - { - "custom": { - "xLabel": "Oakville", - "yLabel": "139 192" - }, - "category": "Oakville", - "y": 139192 - }, - { - "custom": { - "xLabel": "Saltillo", - "yLabel": "577 352" - }, - "category": "Saltillo", - "y": 577352 - }, - { - "custom": { - "xLabel": "Swansea", - "yLabel": "230 000" - }, - "category": "Swansea", - "y": 230000 - }, - { - "custom": { - "xLabel": "Firozabad", - "yLabel": "215 128" - }, - "category": "Firozabad", - "y": 215128 - }, - { - "custom": { - "xLabel": "Jambi", - "yLabel": "385 201" - }, - "category": "Jambi", - "y": 385201 - }, - { - "custom": { - "xLabel": "Dushanbe", - "yLabel": "524 000" - }, - "category": "Dushanbe", - "y": 524000 - }, - { - "custom": { - "xLabel": "Chimoio", - "yLabel": "171 056" - }, - "category": "Chimoio", - "y": 171056 - }, - { - "custom": { - "xLabel": "Baquba", - "yLabel": "114 516" - }, - "category": "Baquba", - "y": 114516 - }, - { - "custom": { - "xLabel": "Salto", - "yLabel": "96 348" - }, - "category": "Salto", - "y": 96348 - }, - { - "custom": { - "xLabel": "The Valley", - "yLabel": "595" - }, - "category": "The Valley", - "y": 595 - }, - { - "custom": { - "xLabel": "Fort Worth", - "yLabel": "534 694" - }, - "category": "Fort Worth", - "y": 534694 - }, - { - "custom": { - "xLabel": "Nogales", - "yLabel": "159 103" - }, - "category": "Nogales", - "y": 159103 - }, - { - "custom": { - "xLabel": "General Escobedo", - "yLabel": "232 961" - }, - "category": "General Escobedo", - "y": 232961 - }, - { - "custom": { - "xLabel": "Chuzhou", - "yLabel": "125 341" - }, - "category": "Chuzhou", - "y": 125341 - }, - { - "custom": { - "xLabel": "Okazaki", - "yLabel": "328 711" - }, - "category": "Okazaki", - "y": 328711 - }, - { - "custom": { - "xLabel": "Ife", - "yLabel": "296 800" - }, - "category": "Ife", - "y": 296800 - }, - { - "custom": { - "xLabel": "Río Cuarto", - "yLabel": "134 355" - }, - "category": "Río Cuarto", - "y": 134355 - }, - { - "custom": { - "xLabel": "Urawa", - "yLabel": "469 675" - }, - "category": "Urawa", - "y": 469675 - }, - { - "custom": { - "xLabel": "Castilla", - "yLabel": "90 642" - }, - "category": "Castilla", - "y": 90642 - }, - { - "custom": { - "xLabel": "Fuzhou", - "yLabel": "1 593 800" - }, - "category": "Fuzhou", - "y": 1593800 - }, - { - "custom": { - "xLabel": "Mobile", - "yLabel": "198 915" - }, - "category": "Mobile", - "y": 198915 - }, - { - "custom": { - "xLabel": "Dipolog", - "yLabel": "99 862" - }, - "category": "Dipolog", - "y": 99862 - }, - { - "custom": { - "xLabel": "Makijivka", - "yLabel": "384 000" - }, - "category": "Makijivka", - "y": 384000 - }, - { - "custom": { - "xLabel": "Altamira", - "yLabel": "127 490" - }, - "category": "Altamira", - "y": 127490 - }, - { - "custom": { - "xLabel": "Tianshui", - "yLabel": "244 974" - }, - "category": "Tianshui", - "y": 244974 - }, - { - "custom": { - "xLabel": "Fontana", - "yLabel": "128 929" - }, - "category": "Fontana", - "y": 128929 - }, - { - "custom": { - "xLabel": "Cam Pha", - "yLabel": "209 086" - }, - "category": "Cam Pha", - "y": 209086 - }, - { - "custom": { - "xLabel": "Belmopan", - "yLabel": "7 105" - }, - "category": "Belmopan", - "y": 7105 - }, - { - "custom": { - "xLabel": "Yaoundé", - "yLabel": "1 372 800" - }, - "category": "Yaoundé", - "y": 1372800 - }, - { - "custom": { - "xLabel": "Lagos de Moreno", - "yLabel": "127 949" - }, - "category": "Lagos de Moreno", - "y": 127949 - }, - { - "custom": { - "xLabel": "Metepec", - "yLabel": "194 265" - }, - "category": "Metepec", - "y": 194265 - }, - { - "custom": { - "xLabel": "Olinda", - "yLabel": "354 732" - }, - "category": "Olinda", - "y": 354732 - }, - { - "custom": { - "xLabel": "Naltšik", - "yLabel": "233 400" - }, - "category": "Naltšik", - "y": 233400 - }, - { - "custom": { - "xLabel": "Jilin", - "yLabel": "1 040 000" - }, - "category": "Jilin", - "y": 1040000 - }, - { - "custom": { - "xLabel": "Crawley", - "yLabel": "97 000" - }, - "category": "Crawley", - "y": 97000 - }, - { - "custom": { - "xLabel": "Ansan", - "yLabel": "510 314" - }, - "category": "Ansan", - "y": 510314 - }, - { - "custom": { - "xLabel": "Takarazuka", - "yLabel": "205 993" - }, - "category": "Takarazuka", - "y": 205993 - }, - { - "custom": { - "xLabel": "Conakry", - "yLabel": "1 090 610" - }, - "category": "Conakry", - "y": 1090610 - }, - { - "custom": { - "xLabel": "Praia Grande", - "yLabel": "168 434" - }, - "category": "Praia Grande", - "y": 168434 - }, - { - "custom": { - "xLabel": "Matanzas", - "yLabel": "123 273" - }, - "category": "Matanzas", - "y": 123273 - }, - { - "custom": { - "xLabel": "Kisarazu", - "yLabel": "121 967" - }, - "category": "Kisarazu", - "y": 121967 - }, - { - "custom": { - "xLabel": "Arden-Arcade", - "yLabel": "92 040" - }, - "category": "Arden-Arcade", - "y": 92040 - }, - { - "custom": { - "xLabel": "Dongtai", - "yLabel": "192 247" - }, - "category": "Dongtai", - "y": 192247 - }, - { - "custom": { - "xLabel": "San Francisco", - "yLabel": "776 733" - }, - "category": "San Francisco", - "y": 776733 - }, - { - "custom": { - "xLabel": "Iguala de la Independencia", - "yLabel": "123 883" - }, - "category": "Iguala de la Independencia", - "y": 123883 - }, - { - "custom": { - "xLabel": "Geneve", - "yLabel": "173 500" - }, - "category": "Geneve", - "y": 173500 - }, - { - "custom": { - "xLabel": "Sawhaj", - "yLabel": "170 125" - }, - "category": "Sawhaj", - "y": 170125 - }, - { - "custom": { - "xLabel": "Kairouan", - "yLabel": "113 100" - }, - "category": "Kairouan", - "y": 113100 - }, - { - "custom": { - "xLabel": "Jos", - "yLabel": "206 300" - }, - "category": "Jos", - "y": 206300 - }, - { - "custom": { - "xLabel": "Burnaby", - "yLabel": "179 209" - }, - "category": "Burnaby", - "y": 179209 - }, - { - "custom": { - "xLabel": "Barcelona", - "yLabel": "322 267" - }, - "category": "Barcelona", - "y": 322267 - }, - { - "custom": { - "xLabel": "José Azueta", - "yLabel": "95 448" - }, - "category": "José Azueta", - "y": 95448 - }, - { - "custom": { - "xLabel": "Abilene", - "yLabel": "115 930" - }, - "category": "Abilene", - "y": 115930 - }, - { - "custom": { - "xLabel": "Delhi", - "yLabel": "7 206 704" - }, - "category": "Delhi", - "y": 7206704 - }, - { - "custom": { - "xLabel": "Yamoussoukro", - "yLabel": "130 000" - }, - "category": "Yamoussoukro", - "y": 130000 - }, - { - "custom": { - "xLabel": "Luziânia", - "yLabel": "125 597" - }, - "category": "Luziânia", - "y": 125597 - }, - { - "custom": { - "xLabel": "La Romana", - "yLabel": "140 204" - }, - "category": "La Romana", - "y": 140204 - }, - { - "custom": { - "xLabel": "Toledo", - "yLabel": "313 619" - }, - "category": "Toledo", - "y": 313619 - }, - { - "custom": { - "xLabel": "al-Kharj", - "yLabel": "152 100" - }, - "category": "al-Kharj", - "y": 152100 - }, - { - "custom": { - "xLabel": "Livonia", - "yLabel": "100 545" - }, - "category": "Livonia", - "y": 100545 - }, - { - "custom": { - "xLabel": "Bello", - "yLabel": "333 470" - }, - "category": "Bello", - "y": 333470 - }, - { - "custom": { - "xLabel": "al-Raqqa", - "yLabel": "108 020" - }, - "category": "al-Raqqa", - "y": 108020 - }, - { - "custom": { - "xLabel": "Ternopil", - "yLabel": "236 000" - }, - "category": "Ternopil", - "y": 236000 - }, - { - "custom": { - "xLabel": "Belford Roxo", - "yLabel": "425 194" - }, - "category": "Belford Roxo", - "y": 425194 - }, - { - "custom": { - "xLabel": "Mokpo", - "yLabel": "247 452" - }, - "category": "Mokpo", - "y": 247452 - }, - { - "custom": { - "xLabel": "Bergisch Gladbach", - "yLabel": "106 150" - }, - "category": "Bergisch Gladbach", - "y": 106150 - }, - { - "custom": { - "xLabel": "Dumaguete", - "yLabel": "102 265" - }, - "category": "Dumaguete", - "y": 102265 - }, - { - "custom": { - "xLabel": "Sokoto", - "yLabel": "204 900" - }, - "category": "Sokoto", - "y": 204900 - }, - { - "custom": { - "xLabel": "Funabashi", - "yLabel": "545 299" - }, - "category": "Funabashi", - "y": 545299 - }, - { - "custom": { - "xLabel": "Vishakhapatnam", - "yLabel": "752 037" - }, - "category": "Vishakhapatnam", - "y": 752037 - }, - { - "custom": { - "xLabel": "Shomolu", - "yLabel": "147 700" - }, - "category": "Shomolu", - "y": 147700 - }, - { - "custom": { - "xLabel": "Handa", - "yLabel": "108 600" - }, - "category": "Handa", - "y": 108600 - }, - { - "custom": { - "xLabel": "Habarovsk", - "yLabel": "609 400" - }, - "category": "Habarovsk", - "y": 609400 - }, - { - "custom": { - "xLabel": "Chelmsford", - "yLabel": "97 451" - }, - "category": "Chelmsford", - "y": 97451 - }, - { - "custom": { - "xLabel": "Dhaka", - "yLabel": "3 612 850" - }, - "category": "Dhaka", - "y": 3612850 - }, - { - "custom": { - "xLabel": "Chandannagar", - "yLabel": "120 378" - }, - "category": "Chandannagar", - "y": 120378 - }, - { - "custom": { - "xLabel": "Chalco", - "yLabel": "222 201" - }, - "category": "Chalco", - "y": 222201 - }, - { - "custom": { - "xLabel": "Lilongwe", - "yLabel": "435 964" - }, - "category": "Lilongwe", - "y": 435964 - }, - { - "custom": { - "xLabel": "Fuchu", - "yLabel": "220 576" - }, - "category": "Fuchu", - "y": 220576 - }, - { - "custom": { - "xLabel": "Tarragona", - "yLabel": "113 016" - }, - "category": "Tarragona", - "y": 113016 - }, - { - "custom": { - "xLabel": "Tavoy (Dawei)", - "yLabel": "96 800" - }, - "category": "Tavoy (Dawei)", - "y": 96800 - }, - { - "custom": { - "xLabel": "Uberlândia", - "yLabel": "487 222" - }, - "category": "Uberlândia", - "y": 487222 - }, - { - "custom": { - "xLabel": "Molodetšno", - "yLabel": "97 000" - }, - "category": "Molodetšno", - "y": 97000 - }, - { - "custom": { - "xLabel": "Argenteuil", - "yLabel": "93 961" - }, - "category": "Argenteuil", - "y": 93961 - }, - { - "custom": { - "xLabel": "Nanyang", - "yLabel": "243 303" - }, - "category": "Nanyang", - "y": 243303 - }, - { - "custom": { - "xLabel": "Downey", - "yLabel": "107 323" - }, - "category": "Downey", - "y": 107323 - }, - { - "custom": { - "xLabel": "Providence", - "yLabel": "173 618" - }, - "category": "Providence", - "y": 173618 - }, - { - "custom": { - "xLabel": "Hofu", - "yLabel": "118 751" - }, - "category": "Hofu", - "y": 118751 - }, - { - "custom": { - "xLabel": "Besançon", - "yLabel": "117 733" - }, - "category": "Besançon", - "y": 117733 - }, - { - "custom": { - "xLabel": "Torbat-e Heydariyeh", - "yLabel": "94 600" - }, - "category": "Torbat-e Heydariyeh", - "y": 94600 - }, - { - "custom": { - "xLabel": "Ixtlahuaca", - "yLabel": "115 548" - }, - "category": "Ixtlahuaca", - "y": 115548 - }, - { - "custom": { - "xLabel": "San Fernando de Apure", - "yLabel": "93 809" - }, - "category": "San Fernando de Apure", - "y": 93809 - }, - { - "custom": { - "xLabel": "Tlajomulco de Zúñiga", - "yLabel": "123 220" - }, - "category": "Tlajomulco de Zúñiga", - "y": 123220 - }, - { - "custom": { - "xLabel": "Zhengzhou", - "yLabel": "2 107 200" - }, - "category": "Zhengzhou", - "y": 2107200 - }, - { - "custom": { - "xLabel": "Akron", - "yLabel": "217 074" - }, - "category": "Akron", - "y": 217074 - }, - { - "custom": { - "xLabel": "Kaluga", - "yLabel": "339 300" - }, - "category": "Kaluga", - "y": 339300 - }, - { - "custom": { - "xLabel": "Sambalpur", - "yLabel": "131 138" - }, - "category": "Sambalpur", - "y": 131138 - }, - { - "custom": { - "xLabel": "Kamalia", - "yLabel": "95 300" - }, - "category": "Kamalia", - "y": 95300 - }, - { - "custom": { - "xLabel": "Matadi", - "yLabel": "172 730" - }, - "category": "Matadi", - "y": 172730 - }, - { - "custom": { - "xLabel": "Rio Grande", - "yLabel": "182 222" - }, - "category": "Rio Grande", - "y": 182222 - }, - { - "custom": { - "xLabel": "Zanjan", - "yLabel": "286 295" - }, - "category": "Zanjan", - "y": 286295 - }, - { - "custom": { - "xLabel": "Pekan Baru", - "yLabel": "438 638" - }, - "category": "Pekan Baru", - "y": 438638 - }, - { - "custom": { - "xLabel": "Opole", - "yLabel": "129 553" - }, - "category": "Opole", - "y": 129553 - }, - { - "custom": { - "xLabel": "Guasave", - "yLabel": "277 201" - }, - "category": "Guasave", - "y": 277201 - }, - { - "custom": { - "xLabel": "Hirakata", - "yLabel": "403 151" - }, - "category": "Hirakata", - "y": 403151 - }, - { - "custom": { - "xLabel": "Limassol", - "yLabel": "154 400" - }, - "category": "Limassol", - "y": 154400 - }, - { - "custom": { - "xLabel": "Kamarhati", - "yLabel": "266 889" - }, - "category": "Kamarhati", - "y": 266889 - }, - { - "custom": { - "xLabel": "Vanderbijlpark", - "yLabel": "468 931" - }, - "category": "Vanderbijlpark", - "y": 468931 - }, - { - "custom": { - "xLabel": "Tottori", - "yLabel": "147 523" - }, - "category": "Tottori", - "y": 147523 - }, - { - "custom": { - "xLabel": "Hayward", - "yLabel": "140 030" - }, - "category": "Hayward", - "y": 140030 - }, - { - "custom": { - "xLabel": "Tarsus", - "yLabel": "246 206" - }, - "category": "Tarsus", - "y": 246206 - }, - { - "custom": { - "xLabel": "Pereira", - "yLabel": "381 725" - }, - "category": "Pereira", - "y": 381725 - }, - { - "custom": { - "xLabel": "al-Amara", - "yLabel": "208 797" - }, - "category": "al-Amara", - "y": 208797 - }, - { - "custom": { - "xLabel": "Breda", - "yLabel": "160 398" - }, - "category": "Breda", - "y": 160398 - }, - { - "custom": { - "xLabel": "Giron", - "yLabel": "90 688" - }, - "category": "Giron", - "y": 90688 - }, - { - "custom": { - "xLabel": "Mahajanga", - "yLabel": "100 807" - }, - "category": "Mahajanga", - "y": 100807 - }, - { - "custom": { - "xLabel": "Vejalpur", - "yLabel": "89 053" - }, - "category": "Vejalpur", - "y": 89053 - }, - { - "custom": { - "xLabel": "Minatitlán", - "yLabel": "152 983" - }, - "category": "Minatitlán", - "y": 152983 - }, - { - "custom": { - "xLabel": "Worthing", - "yLabel": "100 000" - }, - "category": "Worthing", - "y": 100000 - }, - { - "custom": { - "xLabel": "Zaanstad", - "yLabel": "135 621" - }, - "category": "Zaanstad", - "y": 135621 - }, - { - "custom": { - "xLabel": "Basra", - "yLabel": "406 296" - }, - "category": "Basra", - "y": 406296 - }, - { - "custom": { - "xLabel": "Jining", - "yLabel": "163 552" - }, - "category": "Jining", - "y": 163552 - }, - { - "custom": { - "xLabel": "Lashio (Lasho)", - "yLabel": "107 600" - }, - "category": "Lashio (Lasho)", - "y": 107600 - }, - { - "custom": { - "xLabel": "Ube", - "yLabel": "175 206" - }, - "category": "Ube", - "y": 175206 - }, - { - "custom": { - "xLabel": "Heze", - "yLabel": "189 293" - }, - "category": "Heze", - "y": 189293 - }, - { - "custom": { - "xLabel": "Rehovot", - "yLabel": "90 300" - }, - "category": "Rehovot", - "y": 90300 - }, - { - "custom": { - "xLabel": "Sirsa", - "yLabel": "125 000" - }, - "category": "Sirsa", - "y": 125000 - }, - { - "custom": { - "xLabel": "Aizawl", - "yLabel": "155 240" - }, - "category": "Aizawl", - "y": 155240 - }, - { - "custom": { - "xLabel": "Gondiya", - "yLabel": "109 470" - }, - "category": "Gondiya", - "y": 109470 - }, - { - "custom": { - "xLabel": "Konan", - "yLabel": "95 521" - }, - "category": "Konan", - "y": 95521 - }, - { - "custom": { - "xLabel": "Tellicherry (Thalassery)", - "yLabel": "103 579" - }, - "category": "Tellicherry (Thalassery)", - "y": 103579 - }, - { - "custom": { - "xLabel": "Gibraltar", - "yLabel": "27 025" - }, - "category": "Gibraltar", - "y": 27025 - }, - { - "custom": { - "xLabel": "Sevastopol", - "yLabel": "348 000" - }, - "category": "Sevastopol", - "y": 348000 - }, - { - "custom": { - "xLabel": "Dewas", - "yLabel": "164 364" - }, - "category": "Dewas", - "y": 164364 - }, - { - "custom": { - "xLabel": "Valle de Santiago", - "yLabel": "130 557" - }, - "category": "Valle de Santiago", - "y": 130557 - }, - { - "custom": { - "xLabel": "Nova Friburgo", - "yLabel": "170 697" - }, - "category": "Nova Friburgo", - "y": 170697 - }, - { - "custom": { - "xLabel": "Korolev", - "yLabel": "132 400" - }, - "category": "Korolev", - "y": 132400 - }, - { - "custom": { - "xLabel": "Kaiserslautern", - "yLabel": "100 025" - }, - "category": "Kaiserslautern", - "y": 100025 - }, - { - "custom": { - "xLabel": "Antwerpen", - "yLabel": "446 525" - }, - "category": "Antwerpen", - "y": 446525 - }, - { - "custom": { - "xLabel": "Nahodka", - "yLabel": "157 700" - }, - "category": "Nahodka", - "y": 157700 - }, - { - "custom": { - "xLabel": "Medina", - "yLabel": "608 300" - }, - "category": "Medina", - "y": 608300 - }, - { - "custom": { - "xLabel": "Almería", - "yLabel": "169 027" - }, - "category": "Almería", - "y": 169027 - }, - { - "custom": { - "xLabel": "Saidpur", - "yLabel": "96 777" - }, - "category": "Saidpur", - "y": 96777 - }, - { - "custom": { - "xLabel": "Doha", - "yLabel": "355 000" - }, - "category": "Doha", - "y": 355000 - }, - { - "custom": { - "xLabel": "Bragança Paulista", - "yLabel": "116 929" - }, - "category": "Bragança Paulista", - "y": 116929 - }, - { - "custom": { - "xLabel": "Namangan", - "yLabel": "370 500" - }, - "category": "Namangan", - "y": 370500 - }, - { - "custom": { - "xLabel": "Plovdiv", - "yLabel": "342 584" - }, - "category": "Plovdiv", - "y": 342584 - }, - { - "custom": { - "xLabel": "Botshabelo", - "yLabel": "177 971" - }, - "category": "Botshabelo", - "y": 177971 - }, - { - "custom": { - "xLabel": "Zunyi", - "yLabel": "261 862" - }, - "category": "Zunyi", - "y": 261862 - }, - { - "custom": { - "xLabel": "Barreiras", - "yLabel": "127 801" - }, - "category": "Barreiras", - "y": 127801 - }, - { - "custom": { - "xLabel": "Ribeirão das Neves", - "yLabel": "232 685" - }, - "category": "Ribeirão das Neves", - "y": 232685 - }, - { - "custom": { - "xLabel": "Manisa", - "yLabel": "207 148" - }, - "category": "Manisa", - "y": 207148 - }, - { - "custom": { - "xLabel": "Montes Claros", - "yLabel": "286 058" - }, - "category": "Montes Claros", - "y": 286058 - }, - { - "custom": { - "xLabel": "al-Ramadi", - "yLabel": "192 556" - }, - "category": "al-Ramadi", - "y": 192556 - }, - { - "custom": { - "xLabel": "Sariwon", - "yLabel": "254 146" - }, - "category": "Sariwon", - "y": 254146 - }, - { - "custom": { - "xLabel": "Norwich", - "yLabel": "124 000" - }, - "category": "Norwich", - "y": 124000 - }, - { - "custom": { - "xLabel": "Ourense (Orense)", - "yLabel": "109 120" - }, - "category": "Ourense (Orense)", - "y": 109120 - }, - { - "custom": { - "xLabel": "Wah", - "yLabel": "198 400" - }, - "category": "Wah", - "y": 198400 - }, - { - "custom": { - "xLabel": "Prokopjevsk", - "yLabel": "237 300" - }, - "category": "Prokopjevsk", - "y": 237300 - }, - { - "custom": { - "xLabel": "Arica", - "yLabel": "189 036" - }, - "category": "Arica", - "y": 189036 - }, - { - "custom": { - "xLabel": "Ilam", - "yLabel": "126 346" - }, - "category": "Ilam", - "y": 126346 - }, - { - "custom": { - "xLabel": "Puri", - "yLabel": "125 199" - }, - "category": "Puri", - "y": 125199 - }, - { - "custom": { - "xLabel": "Denver", - "yLabel": "554 636" - }, - "category": "Denver", - "y": 554636 - }, - { - "custom": { - "xLabel": "Novotroitsk", - "yLabel": "109 600" - }, - "category": "Novotroitsk", - "y": 109600 - }, - { - "custom": { - "xLabel": "Taliao", - "yLabel": "115 897" - }, - "category": "Taliao", - "y": 115897 - }, - { - "custom": { - "xLabel": "Sliven", - "yLabel": "105 530" - }, - "category": "Sliven", - "y": 105530 - }, - { - "custom": { - "xLabel": "San Jose", - "yLabel": "108 254" - }, - "category": "San Jose", - "y": 108254 - }, - { - "custom": { - "xLabel": "Termiz", - "yLabel": "109 500" - }, - "category": "Termiz", - "y": 109500 - }, - { - "custom": { - "xLabel": "Mandaue", - "yLabel": "259 728" - }, - "category": "Mandaue", - "y": 259728 - }, - { - "custom": { - "xLabel": "Kuantan", - "yLabel": "199 484" - }, - "category": "Kuantan", - "y": 199484 - }, - { - "custom": { - "xLabel": "Kütahya", - "yLabel": "144 761" - }, - "category": "Kütahya", - "y": 144761 - }, - { - "custom": { - "xLabel": "San Nicolás de los Arroyos", - "yLabel": "119 302" - }, - "category": "San Nicolás de los Arroyos", - "y": 119302 - }, - { - "custom": { - "xLabel": "Manchester", - "yLabel": "430 000" - }, - "category": "Manchester", - "y": 430000 - }, - { - "custom": { - "xLabel": "Crato", - "yLabel": "98 965" - }, - "category": "Crato", - "y": 98965 - }, - { - "custom": { - "xLabel": "Urmia", - "yLabel": "435 200" - }, - "category": "Urmia", - "y": 435200 - }, - { - "custom": { - "xLabel": "Carolina", - "yLabel": "186 076" - }, - "category": "Carolina", - "y": 186076 - }, - { - "custom": { - "xLabel": "Austin", - "yLabel": "656 562" - }, - "category": "Austin", - "y": 656562 - }, - { - "custom": { - "xLabel": "Santiago", - "yLabel": "110 531" - }, - "category": "Santiago", - "y": 110531 - }, - { - "custom": { - "xLabel": "Sumqayit", - "yLabel": "283 000" - }, - "category": "Sumqayit", - "y": 283000 - }, - { - "custom": { - "xLabel": "Ijebu-Ode", - "yLabel": "156 400" - }, - "category": "Ijebu-Ode", - "y": 156400 - }, - { - "custom": { - "xLabel": "Lausanne", - "yLabel": "114 500" - }, - "category": "Lausanne", - "y": 114500 - }, - { - "custom": { - "xLabel": "Tongchuan", - "yLabel": "280 657" - }, - "category": "Tongchuan", - "y": 280657 - }, - { - "custom": { - "xLabel": "Umeå", - "yLabel": "104 512" - }, - "category": "Umeå", - "y": 104512 - }, - { - "custom": { - "xLabel": "Chengdu", - "yLabel": "3 361 500" - }, - "category": "Chengdu", - "y": 3361500 - }, - { - "custom": { - "xLabel": "al-Diwaniya", - "yLabel": "196 519" - }, - "category": "al-Diwaniya", - "y": 196519 - }, - { - "custom": { - "xLabel": "Hospet", - "yLabel": "96 322" - }, - "category": "Hospet", - "y": 96322 - }, - { - "custom": { - "xLabel": "San Carlos", - "yLabel": "118 259" - }, - "category": "San Carlos", - "y": 118259 - }, - { - "custom": { - "xLabel": "Fort Collins", - "yLabel": "118 652" - }, - "category": "Fort Collins", - "y": 118652 - }, - { - "custom": { - "xLabel": "Meknès", - "yLabel": "460 000" - }, - "category": "Meknès", - "y": 460000 - }, - { - "custom": { - "xLabel": "Bijapur", - "yLabel": "186 939" - }, - "category": "Bijapur", - "y": 186939 - }, - { - "custom": { - "xLabel": "Utrecht", - "yLabel": "234 323" - }, - "category": "Utrecht", - "y": 234323 - }, - { - "custom": { - "xLabel": "Nobeoka", - "yLabel": "125 547" - }, - "category": "Nobeoka", - "y": 125547 - }, - { - "custom": { - "xLabel": "Ramat Gan", - "yLabel": "126 900" - }, - "category": "Ramat Gan", - "y": 126900 - }, - { - "custom": { - "xLabel": "Mendoza", - "yLabel": "123 027" - }, - "category": "Mendoza", - "y": 123027 - }, - { - "custom": { - "xLabel": "Mission Viejo", - "yLabel": "98 049" - }, - "category": "Mission Viejo", - "y": 98049 - }, - { - "custom": { - "xLabel": "Meixian", - "yLabel": "132 156" - }, - "category": "Meixian", - "y": 132156 - }, - { - "custom": { - "xLabel": "Blida (el-Boulaida)", - "yLabel": "127 284" - }, - "category": "Blida (el-Boulaida)", - "y": 127284 - }, - { - "custom": { - "xLabel": "Colima", - "yLabel": "129 454" - }, - "category": "Colima", - "y": 129454 - }, - { - "custom": { - "xLabel": "Shaowu", - "yLabel": "90 286" - }, - "category": "Shaowu", - "y": 90286 - }, - { - "custom": { - "xLabel": "Balašiha", - "yLabel": "132 900" - }, - "category": "Balašiha", - "y": 132900 - }, - { - "custom": { - "xLabel": "Saveh", - "yLabel": "111 245" - }, - "category": "Saveh", - "y": 111245 - }, - { - "custom": { - "xLabel": "Nakhon Sawan", - "yLabel": "123 800" - }, - "category": "Nakhon Sawan", - "y": 123800 - }, - { - "custom": { - "xLabel": "Shahjahanpur", - "yLabel": "237 713" - }, - "category": "Shahjahanpur", - "y": 237713 - }, - { - "custom": { - "xLabel": "Joliet", - "yLabel": "106 221" - }, - "category": "Joliet", - "y": 106221 - }, - { - "custom": { - "xLabel": "Kokubunji", - "yLabel": "106 996" - }, - "category": "Kokubunji", - "y": 106996 - }, - { - "custom": { - "xLabel": "Xianning", - "yLabel": "136 811" - }, - "category": "Xianning", - "y": 136811 - }, - { - "custom": { - "xLabel": "Wien", - "yLabel": "1 608 144" - }, - "category": "Wien", - "y": 1608144 - }, - { - "custom": { - "xLabel": "Petare", - "yLabel": "488 868" - }, - "category": "Petare", - "y": 488868 - }, - { - "custom": { - "xLabel": "Warri", - "yLabel": "126 100" - }, - "category": "Warri", - "y": 126100 - }, - { - "custom": { - "xLabel": "Petah Tiqwa", - "yLabel": "159 400" - }, - "category": "Petah Tiqwa", - "y": 159400 - }, - { - "custom": { - "xLabel": "El Alto", - "yLabel": "534 466" - }, - "category": "El Alto", - "y": 534466 - }, - { - "custom": { - "xLabel": "Fayetteville", - "yLabel": "121 015" - }, - "category": "Fayetteville", - "y": 121015 - }, - { - "custom": { - "xLabel": "Orlando", - "yLabel": "185 951" - }, - "category": "Orlando", - "y": 185951 - }, - { - "custom": { - "xLabel": "Ufa", - "yLabel": "1 091 200" - }, - "category": "Ufa", - "y": 1091200 - }, - { - "custom": { - "xLabel": "Portmore", - "yLabel": "99 799" - }, - "category": "Portmore", - "y": 99799 - }, - { - "custom": { - "xLabel": "San Miguel", - "yLabel": "127 696" - }, - "category": "San Miguel", - "y": 127696 - }, - { - "custom": { - "xLabel": "Roubaix", - "yLabel": "96 984" - }, - "category": "Roubaix", - "y": 96984 - }, - { - "custom": { - "xLabel": "Kraków", - "yLabel": "738 150" - }, - "category": "Kraków", - "y": 738150 - }, - { - "custom": { - "xLabel": "Dunhua", - "yLabel": "235 100" - }, - "category": "Dunhua", - "y": 235100 - }, - { - "custom": { - "xLabel": "Pasig", - "yLabel": "505 058" - }, - "category": "Pasig", - "y": 505058 - }, - { - "custom": { - "xLabel": "Çorum", - "yLabel": "145 495" - }, - "category": "Çorum", - "y": 145495 - }, - { - "custom": { - "xLabel": "Bandirma", - "yLabel": "90 200" - }, - "category": "Bandirma", - "y": 90200 - }, - { - "custom": { - "xLabel": "Almaty", - "yLabel": "1 129 400" - }, - "category": "Almaty", - "y": 1129400 - }, - { - "custom": { - "xLabel": "Maunath Bhanjan", - "yLabel": "136 697" - }, - "category": "Maunath Bhanjan", - "y": 136697 - }, - { - "custom": { - "xLabel": "Campos dos Goytacazes", - "yLabel": "398 418" - }, - "category": "Campos dos Goytacazes", - "y": 398418 - }, - { - "custom": { - "xLabel": "Camagüey", - "yLabel": "298 726" - }, - "category": "Camagüey", - "y": 298726 - }, - { - "custom": { - "xLabel": "Fukushima", - "yLabel": "287 525" - }, - "category": "Fukushima", - "y": 287525 - }, - { - "custom": { - "xLabel": "Itapetininga", - "yLabel": "119 391" - }, - "category": "Itapetininga", - "y": 119391 - }, - { - "custom": { - "xLabel": "Chong-up", - "yLabel": "139 111" - }, - "category": "Chong-up", - "y": 139111 - }, - { - "custom": { - "xLabel": "Noda", - "yLabel": "121 030" - }, - "category": "Noda", - "y": 121030 - }, - { - "custom": { - "xLabel": "Settat", - "yLabel": "96 200" - }, - "category": "Settat", - "y": 96200 - }, - { - "custom": { - "xLabel": "Longkou", - "yLabel": "148 362" - }, - "category": "Longkou", - "y": 148362 - }, - { - "custom": { - "xLabel": "Datong", - "yLabel": "800 000" - }, - "category": "Datong", - "y": 800000 - }, - { - "custom": { - "xLabel": "Lubbock", - "yLabel": "199 564" - }, - "category": "Lubbock", - "y": 199564 - }, - { - "custom": { - "xLabel": "Santa Clarita", - "yLabel": "151 088" - }, - "category": "Santa Clarita", - "y": 151088 - }, - { - "custom": { - "xLabel": "Hassan", - "yLabel": "90 803" - }, - "category": "Hassan", - "y": 90803 - }, - { - "custom": { - "xLabel": "General Mariano Alvarez", - "yLabel": "112 446" - }, - "category": "General Mariano Alvarez", - "y": 112446 - }, - { - "custom": { - "xLabel": "San Pedro de Macorís", - "yLabel": "124 735" - }, - "category": "San Pedro de Macorís", - "y": 124735 - }, - { - "custom": { - "xLabel": "Ligao", - "yLabel": "90 603" - }, - "category": "Ligao", - "y": 90603 - }, - { - "custom": { - "xLabel": "Komatsu", - "yLabel": "107 937" - }, - "category": "Komatsu", - "y": 107937 - }, - { - "custom": { - "xLabel": "Maseru", - "yLabel": "297 000" - }, - "category": "Maseru", - "y": 297000 - }, - { - "custom": { - "xLabel": "Kuznetsk", - "yLabel": "98 200" - }, - "category": "Kuznetsk", - "y": 98200 - }, - { - "custom": { - "xLabel": "Haldia", - "yLabel": "100 347" - }, - "category": "Haldia", - "y": 100347 - }, - { - "custom": { - "xLabel": "Kaifeng", - "yLabel": "510 000" - }, - "category": "Kaifeng", - "y": 510000 - }, - { - "custom": { - "xLabel": "Titagarh", - "yLabel": "114 085" - }, - "category": "Titagarh", - "y": 114085 - }, - { - "custom": { - "xLabel": "Digos", - "yLabel": "125 171" - }, - "category": "Digos", - "y": 125171 - }, - { - "custom": { - "xLabel": "Esfahan", - "yLabel": "1 266 072" - }, - "category": "Esfahan", - "y": 1266072 - }, - { - "custom": { - "xLabel": "Cuernavaca", - "yLabel": "337 966" - }, - "category": "Cuernavaca", - "y": 337966 - }, - { - "custom": { - "xLabel": "Šumen", - "yLabel": "94 686" - }, - "category": "Šumen", - "y": 94686 - }, - { - "custom": { - "xLabel": "Ichihara", - "yLabel": "279 280" - }, - "category": "Ichihara", - "y": 279280 - }, - { - "custom": { - "xLabel": "Atizapán de Zaragoza", - "yLabel": "467 262" - }, - "category": "Atizapán de Zaragoza", - "y": 467262 - }, - { - "custom": { - "xLabel": "Surendranagar", - "yLabel": "105 973" - }, - "category": "Surendranagar", - "y": 105973 - }, - { - "custom": { - "xLabel": "Foggia", - "yLabel": "154 891" - }, - "category": "Foggia", - "y": 154891 - }, - { - "custom": { - "xLabel": "Tulcea", - "yLabel": "96 278" - }, - "category": "Tulcea", - "y": 96278 - }, - { - "custom": { - "xLabel": "Salt Lake City", - "yLabel": "181 743" - }, - "category": "Salt Lake City", - "y": 181743 - }, - { - "custom": { - "xLabel": "Nouakchott", - "yLabel": "667 300" - }, - "category": "Nouakchott", - "y": 667300 - }, - { - "custom": { - "xLabel": "Santiago de Chile", - "yLabel": "4 703 954" - }, - "category": "Santiago de Chile", - "y": 4703954 - }, - { - "custom": { - "xLabel": "Qinhuangdao", - "yLabel": "364 972" - }, - "category": "Qinhuangdao", - "y": 364972 - }, - { - "custom": { - "xLabel": "Qarchak", - "yLabel": "142 690" - }, - "category": "Qarchak", - "y": 142690 - }, - { - "custom": { - "xLabel": "San Luis Potosí", - "yLabel": "669 353" - }, - "category": "San Luis Potosí", - "y": 669353 - }, - { - "custom": { - "xLabel": "Zhezqazghan", - "yLabel": "90 000" - }, - "category": "Zhezqazghan", - "y": 90000 - }, - { - "custom": { - "xLabel": "Patos de Minas", - "yLabel": "119 262" - }, - "category": "Patos de Minas", - "y": 119262 - }, - { - "custom": { - "xLabel": "Faridabad", - "yLabel": "703 592" - }, - "category": "Faridabad", - "y": 703592 - }, - { - "custom": { - "xLabel": "Alicante [Alacant]", - "yLabel": "272 432" - }, - "category": "Alicante [Alacant]", - "y": 272432 - }, - { - "custom": { - "xLabel": "Olsztyn", - "yLabel": "170 904" - }, - "category": "Olsztyn", - "y": 170904 - }, - { - "custom": { - "xLabel": "Beira", - "yLabel": "397 368" - }, - "category": "Beira", - "y": 397368 - }, - { - "custom": { - "xLabel": "Pohang", - "yLabel": "508 899" - }, - "category": "Pohang", - "y": 508899 - }, - { - "custom": { - "xLabel": "Aberdeen", - "yLabel": "213 070" - }, - "category": "Aberdeen", - "y": 213070 - }, - { - "custom": { - "xLabel": "Higashikurume", - "yLabel": "111 666" - }, - "category": "Higashikurume", - "y": 111666 - }, - { - "custom": { - "xLabel": "Lhasa", - "yLabel": "120 000" - }, - "category": "Lhasa", - "y": 120000 - }, - { - "custom": { - "xLabel": "Sapporo", - "yLabel": "1 790 886" - }, - "category": "Sapporo", - "y": 1790886 - }, - { - "custom": { - "xLabel": "Udaipur", - "yLabel": "308 571" - }, - "category": "Udaipur", - "y": 308571 - }, - { - "custom": { - "xLabel": "Ocumare del Tuy", - "yLabel": "97 168" - }, - "category": "Ocumare del Tuy", - "y": 97168 - }, - { - "custom": { - "xLabel": "Cametá", - "yLabel": "92 779" - }, - "category": "Cametá", - "y": 92779 - }, - { - "custom": { - "xLabel": "Floridablanca", - "yLabel": "221 913" - }, - "category": "Floridablanca", - "y": 221913 - }, - { - "custom": { - "xLabel": "Huaihua", - "yLabel": "126 785" - }, - "category": "Huaihua", - "y": 126785 - }, - { - "custom": { - "xLabel": "Ocosingo", - "yLabel": "171 495" - }, - "category": "Ocosingo", - "y": 171495 - }, - { - "custom": { - "xLabel": "Campo Grande", - "yLabel": "649 593" - }, - "category": "Campo Grande", - "y": 649593 - }, - { - "custom": { - "xLabel": "Palmdale", - "yLabel": "116 670" - }, - "category": "Palmdale", - "y": 116670 - }, - { - "custom": { - "xLabel": "Blitar", - "yLabel": "122 600" - }, - "category": "Blitar", - "y": 122600 - }, - { - "custom": { - "xLabel": "Victoria", - "yLabel": "262 686" - }, - "category": "Victoria", - "y": 262686 - }, - { - "custom": { - "xLabel": "Toyonaka", - "yLabel": "396 689" - }, - "category": "Toyonaka", - "y": 396689 - }, - { - "custom": { - "xLabel": "Tiruchirapalli", - "yLabel": "387 223" - }, - "category": "Tiruchirapalli", - "y": 387223 - }, - { - "custom": { - "xLabel": "Gdynia", - "yLabel": "253 521" - }, - "category": "Gdynia", - "y": 253521 - }, - { - "custom": { - "xLabel": "Navadwip", - "yLabel": "125 037" - }, - "category": "Navadwip", - "y": 125037 - }, - { - "custom": { - "xLabel": "Niigata", - "yLabel": "497 464" - }, - "category": "Niigata", - "y": 497464 - }, - { - "custom": { - "xLabel": "Huelva", - "yLabel": "140 583" - }, - "category": "Huelva", - "y": 140583 - }, - { - "custom": { - "xLabel": "Aqtöbe", - "yLabel": "253 100" - }, - "category": "Aqtöbe", - "y": 253100 - }, - { - "custom": { - "xLabel": "Espoo", - "yLabel": "213 271" - }, - "category": "Espoo", - "y": 213271 - }, - { - "custom": { - "xLabel": "Jevpatorija", - "yLabel": "112 000" - }, - "category": "Jevpatorija", - "y": 112000 - }, - { - "custom": { - "xLabel": "South Bend", - "yLabel": "107 789" - }, - "category": "South Bend", - "y": 107789 - }, - { - "custom": { - "xLabel": "Monclova", - "yLabel": "193 657" - }, - "category": "Monclova", - "y": 193657 - }, - { - "custom": { - "xLabel": "New Orleans", - "yLabel": "484 674" - }, - "category": "New Orleans", - "y": 484674 - }, - { - "custom": { - "xLabel": "Karachi", - "yLabel": "9 269 265" - }, - "category": "Karachi", - "y": 9269265 - }, - { - "custom": { - "xLabel": "Ebetsu", - "yLabel": "118 805" - }, - "category": "Ebetsu", - "y": 118805 - }, - { - "custom": { - "xLabel": "Giza", - "yLabel": "2 221 868" - }, - "category": "Giza", - "y": 2221868 - }, - { - "custom": { - "xLabel": "Milagro", - "yLabel": "124 177" - }, - "category": "Milagro", - "y": 124177 - }, - { - "custom": { - "xLabel": "Maidstone", - "yLabel": "90 878" - }, - "category": "Maidstone", - "y": 90878 - }, - { - "custom": { - "xLabel": "Suceava", - "yLabel": "118 549" - }, - "category": "Suceava", - "y": 118549 - }, - { - "custom": { - "xLabel": "Torreón", - "yLabel": "529 093" - }, - "category": "Torreón", - "y": 529093 - }, - { - "custom": { - "xLabel": "Sinuiju", - "yLabel": "326 011" - }, - "category": "Sinuiju", - "y": 326011 - }, - { - "custom": { - "xLabel": "Zabol", - "yLabel": "100 887" - }, - "category": "Zabol", - "y": 100887 - }, - { - "custom": { - "xLabel": "Ajman", - "yLabel": "114 395" - }, - "category": "Ajman", - "y": 114395 - }, - { - "custom": { - "xLabel": "Texcoco", - "yLabel": "203 681" - }, - "category": "Texcoco", - "y": 203681 - }, - { - "custom": { - "xLabel": "Kükon", - "yLabel": "190 100" - }, - "category": "Kükon", - "y": 190100 - }, - { - "custom": { - "xLabel": "Marawi", - "yLabel": "131 090" - }, - "category": "Marawi", - "y": 131090 - }, - { - "custom": { - "xLabel": "Suining", - "yLabel": "146 086" - }, - "category": "Suining", - "y": 146086 - }, - { - "custom": { - "xLabel": "Fujimi", - "yLabel": "96 972" - }, - "category": "Fujimi", - "y": 96972 - }, - { - "custom": { - "xLabel": "Tjumen", - "yLabel": "503 400" - }, - "category": "Tjumen", - "y": 503400 - }, - { - "custom": { - "xLabel": "Matamoros", - "yLabel": "91 858" - }, - "category": "Matamoros", - "y": 91858 - }, - { - "custom": { - "xLabel": "Ruse", - "yLabel": "166 467" - }, - "category": "Ruse", - "y": 166467 - }, - { - "custom": { - "xLabel": "Cabo de Santo Agostinho", - "yLabel": "149 964" - }, - "category": "Cabo de Santo Agostinho", - "y": 149964 - }, - { - "custom": { - "xLabel": "Minna", - "yLabel": "136 900" - }, - "category": "Minna", - "y": 136900 - }, - { - "custom": { - "xLabel": "Brisbane", - "yLabel": "1 291 117" - }, - "category": "Brisbane", - "y": 1291117 - }, - { - "custom": { - "xLabel": "Valdivia", - "yLabel": "133 106" - }, - "category": "Valdivia", - "y": 133106 - }, - { - "custom": { - "xLabel": "Limoges", - "yLabel": "133 968" - }, - "category": "Limoges", - "y": 133968 - }, - { - "custom": { - "xLabel": "Panjin", - "yLabel": "362 773" - }, - "category": "Panjin", - "y": 362773 - }, - { - "custom": { - "xLabel": "Kasukabe", - "yLabel": "201 838" - }, - "category": "Kasukabe", - "y": 201838 - }, - { - "custom": { - "xLabel": "Zahedan", - "yLabel": "419 518" - }, - "category": "Zahedan", - "y": 419518 - }, - { - "custom": { - "xLabel": "Ilagan", - "yLabel": "119 990" - }, - "category": "Ilagan", - "y": 119990 - }, - { - "custom": { - "xLabel": "Taubaté", - "yLabel": "229 130" - }, - "category": "Taubaté", - "y": 229130 - }, - { - "custom": { - "xLabel": "Grozny", - "yLabel": "186 000" - }, - "category": "Grozny", - "y": 186000 - }, - { - "custom": { - "xLabel": "Parbhani", - "yLabel": "190 255" - }, - "category": "Parbhani", - "y": 190255 - }, - { - "custom": { - "xLabel": "Portsmouth", - "yLabel": "100 565" - }, - "category": "Portsmouth", - "y": 100565 - }, - { - "custom": { - "xLabel": "Syracuse", - "yLabel": "147 306" - }, - "category": "Syracuse", - "y": 147306 - }, - { - "custom": { - "xLabel": "Kusatsu", - "yLabel": "106 232" - }, - "category": "Kusatsu", - "y": 106232 - }, - { - "custom": { - "xLabel": "Perth", - "yLabel": "1 096 829" - }, - "category": "Perth", - "y": 1096829 - }, - { - "custom": { - "xLabel": "Paulista", - "yLabel": "248 473" - }, - "category": "Paulista", - "y": 248473 - }, - { - "custom": { - "xLabel": "Taman", - "yLabel": "107 000" - }, - "category": "Taman", - "y": 107000 - }, - { - "custom": { - "xLabel": "Bern", - "yLabel": "122 700" - }, - "category": "Bern", - "y": 122700 - }, - { - "custom": { - "xLabel": "Milwaukee", - "yLabel": "596 974" - }, - "category": "Milwaukee", - "y": 596974 - }, - { - "custom": { - "xLabel": "Pingyi", - "yLabel": "89 373" - }, - "category": "Pingyi", - "y": 89373 - }, - { - "custom": { - "xLabel": "Garut", - "yLabel": "95 800" - }, - "category": "Garut", - "y": 95800 - }, - { - "custom": { - "xLabel": "Gorlivka", - "yLabel": "299 000" - }, - "category": "Gorlivka", - "y": 299000 - }, - { - "custom": { - "xLabel": "Korba", - "yLabel": "124 501" - }, - "category": "Korba", - "y": 124501 - }, - { - "custom": { - "xLabel": "Pak Kret", - "yLabel": "126 055" - }, - "category": "Pak Kret", - "y": 126055 - }, - { - "custom": { - "xLabel": "Ravenna", - "yLabel": "138 418" - }, - "category": "Ravenna", - "y": 138418 - }, - { - "custom": { - "xLabel": "El Araich", - "yLabel": "90 400" - }, - "category": "El Araich", - "y": 90400 - }, - { - "custom": { - "xLabel": "Mirzapur-cum-Vindhyachal", - "yLabel": "169 336" - }, - "category": "Mirzapur-cum-Vindhyachal", - "y": 169336 - }, - { - "custom": { - "xLabel": "Melipilla", - "yLabel": "91 056" - }, - "category": "Melipilla", - "y": 91056 - }, - { - "custom": { - "xLabel": "La Paz", - "yLabel": "758 141" - }, - "category": "La Paz", - "y": 758141 - }, - { - "custom": { - "xLabel": "Pasto", - "yLabel": "332 396" - }, - "category": "Pasto", - "y": 332396 - }, - { - "custom": { - "xLabel": "Ashqelon", - "yLabel": "92 300" - }, - "category": "Ashqelon", - "y": 92300 - }, - { - "custom": { - "xLabel": "Ogbomosho", - "yLabel": "730 000" - }, - "category": "Ogbomosho", - "y": 730000 - }, - { - "custom": { - "xLabel": "Masjed-e-Soleyman", - "yLabel": "116 883" - }, - "category": "Masjed-e-Soleyman", - "y": 116883 - }, - { - "custom": { - "xLabel": "Volzski", - "yLabel": "286 900" - }, - "category": "Volzski", - "y": 286900 - }, - { - "custom": { - "xLabel": "Kamyšin", - "yLabel": "124 600" - }, - "category": "Kamyšin", - "y": 124600 - }, - { - "custom": { - "xLabel": "Otaru", - "yLabel": "155 784" - }, - "category": "Otaru", - "y": 155784 - }, - { - "custom": { - "xLabel": "Jiamusi", - "yLabel": "493 409" - }, - "category": "Jiamusi", - "y": 493409 - }, - { - "custom": { - "xLabel": "Gebze", - "yLabel": "264 170" - }, - "category": "Gebze", - "y": 264170 - }, - { - "custom": { - "xLabel": "Pasadena", - "yLabel": "141 674" - }, - "category": "Pasadena", - "y": 141674 - }, - { - "custom": { - "xLabel": "Palayankottai", - "yLabel": "97 662" - }, - "category": "Palayankottai", - "y": 97662 - }, - { - "custom": { - "xLabel": "Chaohu", - "yLabel": "123 676" - }, - "category": "Chaohu", - "y": 123676 - }, - { - "custom": { - "xLabel": "Jinzhou", - "yLabel": "570 000" - }, - "category": "Jinzhou", - "y": 570000 - }, - { - "custom": { - "xLabel": "Tébessa", - "yLabel": "112 007" - }, - "category": "Tébessa", - "y": 112007 - }, - { - "custom": { - "xLabel": "Green Bay", - "yLabel": "102 313" - }, - "category": "Green Bay", - "y": 102313 - }, - { - "custom": { - "xLabel": "Singapore", - "yLabel": "4 017 733" - }, - "category": "Singapore", - "y": 4017733 - }, - { - "custom": { - "xLabel": "al-Zarqa", - "yLabel": "389 815" - }, - "category": "al-Zarqa", - "y": 389815 - }, - { - "custom": { - "xLabel": "Talisay", - "yLabel": "148 110" - }, - "category": "Talisay", - "y": 148110 - }, - { - "custom": { - "xLabel": "Hailar", - "yLabel": "180 650" - }, - "category": "Hailar", - "y": 180650 - }, - { - "custom": { - "xLabel": "Lugansk", - "yLabel": "469 000" - }, - "category": "Lugansk", - "y": 469000 - }, - { - "custom": { - "xLabel": "Puno", - "yLabel": "101 578" - }, - "category": "Puno", - "y": 101578 - }, - { - "custom": { - "xLabel": "Jakutsk", - "yLabel": "195 400" - }, - "category": "Jakutsk", - "y": 195400 - }, - { - "custom": { - "xLabel": "Liupanshui", - "yLabel": "363 954" - }, - "category": "Liupanshui", - "y": 363954 - }, - { - "custom": { - "xLabel": "Jundíaí", - "yLabel": "296 127" - }, - "category": "Jundíaí", - "y": 296127 - }, - { - "custom": { - "xLabel": "Lungtan", - "yLabel": "103 088" - }, - "category": "Lungtan", - "y": 103088 - }, - { - "custom": { - "xLabel": "Francistown", - "yLabel": "101 805" - }, - "category": "Francistown", - "y": 101805 - }, - { - "custom": { - "xLabel": "Huntington Beach", - "yLabel": "189 594" - }, - "category": "Huntington Beach", - "y": 189594 - }, - { - "custom": { - "xLabel": "Lucknow", - "yLabel": "1 619 115" - }, - "category": "Lucknow", - "y": 1619115 - }, - { - "custom": { - "xLabel": "Sekondi-Takoradi", - "yLabel": "103 653" - }, - "category": "Sekondi-Takoradi", - "y": 103653 - }, - { - "custom": { - "xLabel": "West Valley City", - "yLabel": "108 896" - }, - "category": "West Valley City", - "y": 108896 - }, - { - "custom": { - "xLabel": "Kafr al-Shaykh", - "yLabel": "124 819" - }, - "category": "Kafr al-Shaykh", - "y": 124819 - }, - { - "custom": { - "xLabel": "Bishkek", - "yLabel": "589 400" - }, - "category": "Bishkek", - "y": 589400 - }, - { - "custom": { - "xLabel": "Hamburg", - "yLabel": "1 704 735" - }, - "category": "Hamburg", - "y": 1704735 - }, - { - "custom": { - "xLabel": "Yakeshi", - "yLabel": "377 869" - }, - "category": "Yakeshi", - "y": 377869 - }, - { - "custom": { - "xLabel": "Shaoguan", - "yLabel": "350 043" - }, - "category": "Shaoguan", - "y": 350043 - }, - { - "custom": { - "xLabel": "Novotšeboksarsk", - "yLabel": "123 400" - }, - "category": "Novotšeboksarsk", - "y": 123400 - }, - { - "custom": { - "xLabel": "Port Moresby", - "yLabel": "247 000" - }, - "category": "Port Moresby", - "y": 247000 - }, - { - "custom": { - "xLabel": "Syrakusa", - "yLabel": "126 282" - }, - "category": "Syrakusa", - "y": 126282 - }, - { - "custom": { - "xLabel": "Penza", - "yLabel": "532 200" - }, - "category": "Penza", - "y": 532200 - }, - { - "custom": { - "xLabel": "Longueuil", - "yLabel": "127 977" - }, - "category": "Longueuil", - "y": 127977 - }, - { - "custom": { - "xLabel": "Chinju", - "yLabel": "329 886" - }, - "category": "Chinju", - "y": 329886 - }, - { - "custom": { - "xLabel": "General Santos", - "yLabel": "411 822" - }, - "category": "General Santos", - "y": 411822 - }, - { - "custom": { - "xLabel": "El-Aaiún", - "yLabel": "169 000" - }, - "category": "El-Aaiún", - "y": 169000 - }, - { - "custom": { - "xLabel": "Maoming", - "yLabel": "178 683" - }, - "category": "Maoming", - "y": 178683 - }, - { - "custom": { - "xLabel": "Poznan", - "yLabel": "576 899" - }, - "category": "Poznan", - "y": 576899 - }, - { - "custom": { - "xLabel": "Amritsar", - "yLabel": "708 835" - }, - "category": "Amritsar", - "y": 708835 - }, - { - "custom": { - "xLabel": "Carrefour", - "yLabel": "290 204" - }, - "category": "Carrefour", - "y": 290204 - }, - { - "custom": { - "xLabel": "Noginsk", - "yLabel": "117 200" - }, - "category": "Noginsk", - "y": 117200 - }, - { - "custom": { - "xLabel": "Bærum", - "yLabel": "101 340" - }, - "category": "Bærum", - "y": 101340 - }, - { - "custom": { - "xLabel": "Alagoinhas", - "yLabel": "126 820" - }, - "category": "Alagoinhas", - "y": 126820 - }, - { - "custom": { - "xLabel": "Ichon", - "yLabel": "155 332" - }, - "category": "Ichon", - "y": 155332 - }, - { - "custom": { - "xLabel": "Temuco", - "yLabel": "233 041" - }, - "category": "Temuco", - "y": 233041 - }, - { - "custom": { - "xLabel": "Sapele", - "yLabel": "139 200" - }, - "category": "Sapele", - "y": 139200 - }, - { - "custom": { - "xLabel": "Hami", - "yLabel": "161 315" - }, - "category": "Hami", - "y": 161315 - }, - { - "custom": { - "xLabel": "Takasago", - "yLabel": "97 632" - }, - "category": "Takasago", - "y": 97632 - }, - { - "custom": { - "xLabel": "Pisa", - "yLabel": "92 379" - }, - "category": "Pisa", - "y": 92379 - }, - { - "custom": { - "xLabel": "Rotherham", - "yLabel": "121 380" - }, - "category": "Rotherham", - "y": 121380 - }, - { - "custom": { - "xLabel": "Kostjantynivka", - "yLabel": "95 000" - }, - "category": "Kostjantynivka", - "y": 95000 - }, - { - "custom": { - "xLabel": "Jhelum", - "yLabel": "145 800" - }, - "category": "Jhelum", - "y": 145800 - }, - { - "custom": { - "xLabel": "Assuan", - "yLabel": "219 017" - }, - "category": "Assuan", - "y": 219017 - }, - { - "custom": { - "xLabel": "Juárez", - "yLabel": "1 217 818" - }, - "category": "Juárez", - "y": 1217818 - }, - { - "custom": { - "xLabel": "Lódz", - "yLabel": "800 110" - }, - "category": "Lódz", - "y": 800110 - }, - { - "custom": { - "xLabel": "Mbour", - "yLabel": "109 300" - }, - "category": "Mbour", - "y": 109300, - "radius": 10 - } - ], - "custom": { - "xTitle": "name", - "yTitle": "population", - "pointTitle": "", - "colorTitle": "", - "sizeTitle": "" - } - } - ] - }, - "tooltip": { - "enabled": true - }, - "legend": { - "enabled": false - }, - "yAxis": [ - { - "type": "linear", - "labels": { - "enabled": true - }, - "title": {}, - "grid": { - "enabled": true - }, - "ticks": {} - } - ], - "xAxis": { - "categories": [ - "Faaa", - "Corumbá", - "Zhenjiang", - "Hafar al-Batin", - "Abadan", - "Khouribga", - "Odesa", - "Amol", - "Victoria", - "Negombo", - "Prato", - "Zielona Góra", - "Qujing", - "Tianmen", - "Syzran", - "Toluca", - "Franca", - "Colchester", - "Linfen", - "Sfax", - "Magdeburg", - "Nandyal", - "Tecámac", - "Udine", - "Guwahati (Gauhati)", - "Dniprodzerzynsk", - "Philadelphia", - "Junagadh", - "Gingoog", - "Kaduna", - "Liepaja", - "Surakarta", - "Sirjan", - "Ciudad Ojeda", - "Fort Wayne", - "Moulmein (Mawlamyine)", - "Jinhua", - "Oita", - "Kawaguchi", - "Moshi", - "Ríobamba", - "Baltimore", - "Buzau", - "Sagamihara", - "Uijongbu", - "Alexandria", - "Bialystok", - "Almetjevsk", - "Sangli", - "Zoetermeer", - "Krementšuk", - "Düren", - "San Pablo", - "Amersfoort", - "Qashqar", - "Elista", - "La Spezia", - "Mixco", - "Bahawalpur", - "Qostanay", - "Kolpino", - "Wuhu", - "Pitesti", - "Anápolis", - "Essen", - "Chunchon", - "Cianjur", - "Bahraich", - "Kediri", - "Panzhihua", - "Hradec Králové", - "Petaling Jaya", - "Fall River", - "Albuquerque", - "Puchon", - "Kasugai", - "Almirante Brown", - "Aurora", - "Vanadzor", - "Suzhou", - "Tšerkessk", - "Atlixco", - "Omuta", - "Townsville", - "Avarua", - "Jakarta", - "Passos", - "Buhoro", - "Santa Maria", - "Mogadishu", - "La Habana", - "Dongying", - "Tonalá", - "Petrópolis", - "Jahrom", - "Solihull", - "Bene Beraq", - "Krasnojarsk", - "Gurue", - "Renqiu", - "Chinandega", - "Lublin", - "Tempe", - "Borås", - "Tilburg", - "Boston", - "Shangzi", - "Nonthaburi", - "Changji", - "Evansville", - "Cienfuegos", - "Ujjain", - "Bhubaneswar", - "Nagano", - "Vinh", - "Timisoara", - "San Fernando del Valle de Cata", - "Chiclayo", - "Guaíba", - "Poços de Caldas", - "San Diego", - "Preston", - "Haldwani-cum-Kathgodam", - "Lagos", - "Brugge", - "Stavanger", - "Maracaíbo", - "Aba", - "Niihama", - "Torino", - "Haarlemmermeer", - "Vancouver", - "Ceské Budejovice", - "Midnapore (Medinipur)", - "Exeter", - "Talavera", - "Novomoskovsk", - "North Barrackpur", - "Šostka", - "Navojoa", - "San Jose", - "Zaria", - "Marand", - "Bergen", - "Košice", - "Comitán de Domínguez", - "Chongju", - "Duisburg", - "Xai-Xai", - "Ibadan", - "Manizales", - "Hims", - "Gorakhpur", - "Johor Baharu", - "Alessandria", - "Helsinki [Helsingfors]", - "Borujerd", - "Trujillo", - "Tbilisi", - "Yangsan", - "Gómez Palacio", - "Konotop", - "Habikino", - "Saint Paul", - "Independence", - "Zagreb", - "Idlib", - "Kalemie", - "Tali", - "Focsani", - "Garland", - "Bekasi", - "São Vicente", - "Badajoz", - "León", - "Takamatsu", - "Grenoble", - "Ashdod", - "Bacoor", - "Uruapan", - "San Pedro Sula", - "Wad Madani", - "Inanda", - "Tamuning", - "Coacalco de Berriozábal", - "Capas", - "Miami", - "Long Xuyen", - "Mexicali", - "Southampton", - "João Pessoa", - "Serekunda", - "Ikire", - "Casablanca", - "Kakogawa", - "Aksaray", - "Grimsby", - "Corona", - "Kovrov", - "Belgaum", - "Manzanillo", - "Gujrat", - "Palangka Raya", - "Pihkova", - "Kanchipuram", - "Davangere", - "Juliaca", - "Anda", - "Richmond", - "Jaranwala", - "Nukus", - "Dodoma", - "Kitakyushu", - "Alwar", - "Aleppo", - "Liuzhou", - "Vung Tau", - "Usak", - "Cabo Frio", - "Jinmen", - "Tlalnepantla de Baz", - "Male", - "Marilao", - "Carapicuíba", - "Dortmund", - "Vaduz", - "Seto", - "Barrackpur", - "Sagar", - "Kuala Terengganu", - "Rondonópolis", - "Bursa", - "Songkhla", - "Mymensingh", - "Talkha", - "Taejon", - "Corpus Christi", - "Mary", - "Yaren", - "Madurai", - "Santo Domingo de Guzmán", - "Arak", - "Shenyang", - "Miandoab", - "Suqian", - "Teófilo Otoni", - "Battambang", - "Veraval", - "Guanare", - "Spanish Town", - "Uitenhage", - "Lutsk", - "Ananindeua", - "El Paso", - "al-Dammam", - "Šiauliai", - "Jieyang", - "Tartu", - "Jiujiang", - "Bagé", - "Leninsk-Kuznetski", - "Makati", - "Ulan Bator", - "Codó", - "Sousse", - "Chofu", - "Meycauayan", - "Maikop", - "Girardot", - "Lanzhou", - "Edirne", - "Kars", - "Jaboatão dos Guararapes", - "Mekka", - "Yixing", - "Godoy Cruz", - "Hegang", - "Pudukkottai", - "Silay", - "Germiston", - "Verona", - "Abeokuta", - "Victoria de las Tunas", - "Tagum", - "Sunggal", - "Eastbourne", - "Paranaguá", - "Bengkulu", - "Shibin al-Kawm", - "Kaiyuan", - "Manaus", - "Kimje", - "Taitung", - "Brasília", - "Akishima", - "Changshu", - "General Trias", - "Podolsk", - "Serang", - "Simi Valley", - "Peking", - "Izevsk", - "Santipur", - "Mbandaka", - "Tabora", - "Naihati", - "Orange", - "Messina", - "Montréal", - "Ankara", - "Pathankot", - "Linhares", - "Fürth", - "Sandakan", - "Petropavlovsk-Kamtšatski", - "Città del Vaticano", - "Ann Arbor", - "Kisangani", - "Chungho", - "Shahr-e Kord", - "Liberec", - "Chilapa de Alvarez", - "Flying Fish Cove", - "Shanghai", - "Novo Hamburgo", - "Daly City", - "Fu´an", - "Arequipa", - "Bamako", - "San Pedro de la Paz", - "Boulder", - "Zanzibar", - "Seversk", - "Yanbu", - "Himki", - "Zinacantepec", - "Yao", - "Kazan", - "Mocuba", - "Memphis", - "Coronel", - "Los Angeles", - "Río Bravo", - "Kashiwazaki", - "Jerusalem", - "Gweru", - "Taizhou", - "Mishima", - "Valletta", - "Derby", - "Mobara", - "Guayaquil", - "Lengshuijiang", - "Benxi", - "Baidyabati", - "Safi", - "Qina", - "Ghardaïa", - "Dordrecht", - "Sri Jayawardenepura Kotte", - "Rennes", - "El Cajon", - "Pavlograd", - "Rosario", - "Kota", - "Kidapawan", - "Paterson", - "Kutaisi", - "Yuncheng", - "Daugavpils", - "Piedras Negras", - "Sertãozinho", - "Machala", - "Higashiosaka", - "Rochdale", - "Vaughan", - "Radom", - "Etobicoke", - "Kollam (Quilon)", - "Novošahtinsk", - "Rostov-na-Donu", - "Jiaxing", - "Taytay", - "Hagen", - "Calapan", - "Dabrowa Górnicza", - "Kasur", - "Nha Trang", - "Kataka (Cuttack)", - "Hikone", - "Kanpur", - "Putian", - "Chingola", - "Kabwe", - "Misato", - "Yamatokoriyama", - "Hitachi", - "Isparta", - "Tantoyuca", - "Kigali", - "Springfield", - "Surgut", - "Zeleznogorsk", - "Tiraspol", - "Itami", - "Chiang Mai", - "Kobe", - "Moji das Cruzes", - "Raj Nandgaon", - "Salerno", - "Sari", - "Bulaq al-Dakrur", - "Milano", - "Ribeirão Preto", - "Severodvinsk", - "Stuttgart", - "Shaoyang", - "Ho Chi Minh City", - "Györ", - "East London", - "Vilnius", - "Suihua", - "Americana", - "Priština", - "Moji-Guaçu", - "Barisal", - "Moers", - "Kuala Lumpur", - "Nojabrsk", - "Boma", - "Yuzhou", - "Hanzhong", - "Cork", - "Ladysmith", - "Embu", - "Mun-gyong", - "Quilpué", - "Pingdu", - "Satu Mare", - "Modinagar", - "Villavicencio", - "Kismaayo", - "Maroua", - "Plano", - "Rawalpindi", - "Daska", - "Porto-Novo", - "Tama", - "Citeureup", - "Wadi al-Sir", - "Melitopol", - "Yibin", - "Baotou", - "Dibrugarh", - "Glasgow", - "Kalisz", - "Likasi", - "Tando Adam", - "Dera Ghazi Khan", - "Goiânia", - "Berhampore (Baharampur)", - "Volgodonsk", - "Legnica", - "Bordeaux", - "San Isidro", - "Kawagoe", - "Yong-in", - "Hanam", - "Asaka", - "Comalcalco", - "Ziguinchor", - "Serov", - "Lakewood", - "Iwo", - "Reynosa", - "Denizli", - "Hyderabad", - "Jamshedpur", - "Bandar Lampung", - "Villa Nueva", - "Ardebil", - "Rizhao", - "Abohar", - "Escondido", - "Newport", - "Lanús", - "Tours", - "Wloclawek", - "Nam Dinh", - "Shuangcheng", - "Pontianak", - "Luchou", - "Cottbus", - "Hadano", - "Cotia", - "Kyiv", - "Wuhan", - "Reutlingen", - "Jammu", - "Kawasaki", - "Nawabganj", - "Kupang", - "West Covina", - "Yosu", - "Takaoka", - "Cochin (Kochi)", - "Portoviejo", - "Mirpur Khas", - "Pinang", - "Hamilton", - "Wakayama", - "Kowloon and New Kowloon", - "Ipatinga", - "Sabadell", - "Djougou", - "Valenzuela", - "Bei´an", - "Kanuma", - "Kakinada", - "Dire Dawa", - "Hafizabad", - "Colombo", - "Valle de Chalco Solidaridad", - "Kioto", - "Urasoe", - "Ivanovo", - "Nice", - "Kabankalan", - "Imus", - "Nova Iguaçu", - "Mesa", - "Toulouse", - "Prome (Pyay)", - "Orjol", - "Eugene", - "Balurghat", - "Las Piñas", - "Deba Habe", - "Citrus Heights", - "Kalookan", - "Fukaya", - "Loudi", - "Avadi", - "Qiqihar", - "Chihuahua", - "Tondabayashi", - "Acheng", - "al-Mansura", - "Blackpool", - "McAllen", - "Örebro", - "Osaka", - "Forlì", - "Tapachula", - "Gonbad-e Qabus", - "Regensburg", - "Tepatitlán de Morelos", - "al-Kut", - "San Salvador de Jujuy", - "Muridke", - "Nijmegen", - "Lyon", - "San Juan Bautista Tuxtepec", - "Xinghua", - "Concepcion", - "Kangnung", - "Berkeley", - "Kashihara", - "Okinawa", - "Krefeld", - "San Buenaventura", - "Machida", - "Santa Ana", - "Rodriguez (Montalban)", - "Mandalay", - "Kenosha", - "Akola", - "Salatiga", - "Serampore", - "Logroño", - "Morelia", - "Tarija", - "Yancheng", - "Hamamatsu", - "Jabaliya", - "Tšernivtsi", - "Nashik (Nasik)", - "Barquisimeto", - "Krasnodar", - "Veracruz", - "Oaxaca de Juárez", - "Tejupilco", - "Yangor", - "Van", - "Guantánamo", - "Masan", - "Sadiqabad", - "Saharanpur", - "Zhangjiagang", - "Bamenda", - "Kumo", - "Cali", - "Saint Louis", - "Fresnillo", - "Lusaka", - "Cimanggis", - "Abidjan", - "Pleven", - "Hama", - "Jackson", - "Medan", - "Quy Nhon", - "Boca del Río", - "Bulandshahr", - "Rampur", - "Ilobu", - "Jingdezhen", - "Chimbote", - "Leicester", - "Bottrop", - "Athens-Clarke County", - "Eluru", - "Kuytun", - "Brownsville", - "San Felipe", - "Olomouc", - "Butembo", - "Sullana", - "Turmero", - "Amagasaki", - "Purwakarta", - "Sangju", - "Ghulja", - "Tachikawa", - "Antalya", - "Yulin", - "Maringá", - "Brno", - "Huaiyin", - "Ettadhamen", - "Odawara", - "Koyang", - "Birkirkara", - "São Caetano do Sul", - "Houston", - "Gütersloh", - "Matsudo", - "Antofagasta", - "Trier", - "Vigo", - "Nagaon", - "al-Sib", - "Calcutta [Kolkata]", - "Temixco", - "Misrata", - "Orsk", - "Navolato", - "Feira de Santana", - "Lincoln", - "Xiaogan", - "Ecatepec de Morelos", - "Navotas", - "Sakado", - "Ipswich", - "Kishiwada", - "Kashan", - "Hannover", - "Pozuelos", - "Isahaya", - "Kitchener", - "Voronez", - "Shulin", - "North Dum Dum", - "Baku", - "Stanley", - "Coral Springs", - "Greensboro", - "Dera Ismail Khan", - "Guarujá", - "Silao", - "My Tho", - "Oldenburg", - "Kawachinagano", - "Chungli", - "Ouagadougou", - "Santa Coloma de Gramenet", - "Ikoma", - "Gainesville", - "Sivas", - "Warren", - "New Bedford", - "Brest", - "Lille", - "Toskent", - "Tuxtla Gutiérrez", - "Hino", - "Gifu", - "Pultava [Poltava]", - "Palhoça", - "Fagatogo", - "Luanshya", - "Bankura", - "Nkongsamba", - "L´Hospitalet de Llobregat", - "Ingraj Bazar (English Bazar)", - "Mito", - "Elblag", - "Raurkela", - "Jokohama [Yokohama]", - "Marv Dasht", - "Sylhet", - "Pate", - "Adoni", - "Gazipur", - "South Dum Dum", - "Onitsha", - "Samara", - "Shaki", - "Port Harcourt", - "Piatra Neamt", - "Hitachinaka", - "Scottsdale", - "Canberra", - "Nazilli", - "Klagenfurt", - "Gorontalo", - "Halle/Saale", - "San Antonio", - "Cheltenham", - "Hildesheim", - "Imabari", - "Irvine", - "Ahvaz", - "London", - "Quilmes", - "Bangui", - "Jalgaon", - "Fuling", - "Zhaoqing", - "Sterling Heights", - "Biên Hoa", - "Sanmenxia", - "Sjeverodonetsk", - "Nakuru", - "Ulhasnagar", - "Qomsheh", - "Tatuí", - "Ado-Ekiti", - "Tambaram", - "Koganei", - "Tong-yong", - "Zelenodolsk", - "Tshikapa", - "Mit Ghamr", - "Erie", - "Ikirun", - "Miami Beach", - "Barcelona", - "Lviv", - "Davenport", - "Râmnicu Vâlcea", - "Perugia", - "Nuevo Laredo", - "Khammam", - "Bani Suwayf", - "Kaili", - "Tenali", - "Barinas", - "Taichung", - "Fujisawa", - "Chiayi", - "Salamanca", - "Niš", - "North York", - "Magelang", - "Qom", - "Kuwana", - "Mbuji-Mayi", - "Santarém", - "Panchiao", - "Mount Darwin", - "Yonago", - "Wolverhampton", - "Guanajuato", - "Purwokerto", - "Georgetown", - "Ruda Slaska", - "Savannah", - "al-Tuqba", - "Tétouan", - "Saint George", - "Maradi", - "Akita", - "Burnpur", - "Bugulma", - "Gloucester", - "Rimini", - "Arkangeli", - "Metz", - "Khamis Mushayt", - "Ituiutaba", - "Montería", - "Samarkand", - "Porbandar", - "Malmö", - "Ota", - "Bahawalnagar", - "Kayseri", - "Cúcuta", - "Pagakku (Pakokku)", - "Talca", - "Ilhéus", - "Hobart", - "Myingyan", - "Sendai", - "San Carlos", - "Caracas", - "Minsk", - "Simferopol", - "Batman", - "Hengyang", - "Faizabad", - "Huntsville", - "Huimanguillo", - "Ciudad del Este", - "Luxor", - "Alor Setar", - "Maribor", - "Anshun", - "Moscow", - "Pikine", - "Quevedo", - "Dijon", - "Chandigarh", - "Dunedin", - "Durgapur", - "Liu´an", - "Surigao", - "Sitapur", - "Tultitlán", - "Hunjiang", - "Heyuan", - "Napoli", - "Pinsk", - "Macuspana", - "Pemalang", - "Binjai", - "Charleroi", - "Amravati", - "Kuri", - "al-Rusayfa", - "Saransk", - "Matsubara", - "Ozamis", - "Sohumi", - "Bayambang", - "Jixi", - "Maxixe", - "Dzerzinsk", - "Angra dos Reis", - "Koshigaya", - "Allappuzha (Alleppey)", - "Santa Rosa", - "Hamhung", - "Chongqing", - "Sirajganj", - "Cajamarca", - "Badalona", - "Bihar Sharif", - "Comilla", - "Petroskoi", - "Chillán", - "Dehra Dun", - "Palma de Mallorca", - "Saint Helier", - "Aguascalientes", - "Joškar-Ola", - "Elgin", - "Albacete", - "Pesaro", - "Málaga", - "San José", - "Kamagaya", - "Mérida", - "Higashimatsuyama", - "Adiyaman", - "Mandi Bahauddin", - "Amoy [Xiamen]", - "Oka-Akoko", - "Nagaoka", - "Gudivada", - "San Juan", - "Mohammedia", - "Akashi", - "Pomona", - "Amadora", - "Latur", - "Solapur (Sholapur)", - "Wuhai", - "Monterrey", - "Ekibastuz", - "Yamaguchi", - "Rajkot", - "Calabozo", - "Laohekou", - "Dayton", - "Meru", - "Purulia", - "Puebla", - "Tunis", - "Bridgetown", - "Mdantsane", - "Raichur", - "Tafuna", - "Chincha Alta", - "Pardubice", - "Yuyao", - "Parnaíba", - "Obihiro", - "Pangkal Pinang", - "San Cristóbal", - "Nanded (Nander)", - "West Bromwich", - "Yangzhou", - "Hailun", - "Garoua", - "Urumtši [Ürümqi]", - "Odense", - "Zhumadian", - "Brovary", - "København", - "Altševsk", - "Lipetsk", - "Tobolsk", - "Ahmadpur East", - "Kanpur Cantonment", - "Las Heras", - "Tórshavn", - "Khanpur", - "Varginha", - "Asyut", - "Semarang", - "Oberhausen", - "Potosí", - "Nagpur", - "Santiago de Cuba", - "Jinchang", - "Bellevue", - "Newcastle", - "Cotonou", - "Zama", - "Jaworzno", - "Mwene-Ditu", - "Bayugan", - "Pindamonhangaba", - "Kirikkale", - "Malabon", - "Rajapalaiyam", - "Caruaru", - "Bucuresti", - "Klin", - "Ismailia", - "Norwalk", - "Jönköping", - "Odintsovo", - "Qods", - "Kameoka", - "Târgu Mures", - "Marabá", - "Emeishan", - "Ceyhan", - "Pinhais", - "Fortaleza", - "Mashhad", - "Polomolok", - "Longyearbyen", - "Belém", - "Santo Domingo de los Colorados", - "Lerma", - "Viransehir", - "Izmit (Kocaeli)", - "Herne", - "Nampula", - "Cheju", - "Cagayan de Oro", - "Uberaba", - "San Felipe del Progreso", - "Kiseljovsk", - "Bhind", - "Frankfurt am Main", - "Surabaya", - "Baton Rouge", - "Sincelejo", - "Jiutai", - "Chapra", - "Malang", - "Douala", - "Sobral", - "Inazawa", - "Eskisehir", - "Kadoma", - "Yichun", - "Paris", - "Banha", - "Zalantun", - "Newark", - "Bacau", - "Ichinomiya", - "Cardiff", - "Sakura", - "Sambhal", - "Cárdenas", - "Champdani", - "Wonju", - "Sarajevo", - "Katsina", - "Cádiz", - "Haora (Howrah)", - "Guangyuan", - "Mataró", - "Catania", - "Erzincan", - "Solikamsk", - "Tecomán", - "Tongliao", - "Nouméa", - "Henderson", - "Tres de Febrero", - "´s-Hertogenbosch", - "Las Margaritas", - "Benito Juárez", - "Varamin", - "Hebron", - "Calgary", - "Compton", - "Hong Gai", - "Poryong", - "Vitoria-Gasteiz", - "Lages", - "Malegaon", - "Resita", - "El Mante", - "Ashoknagar-Kalyangarh", - "Francisco Morato", - "Kariya", - "Leganés", - "Foz do Iguaçu", - "Nuku´alofa", - "Rio de Janeiro", - "Neijiang", - "Virginia Beach", - "Potsdam", - "Oakland", - "Tanjung Pinang", - "Huadian", - "Weno", - "West Island", - "Albany", - "Pécs", - "Tšerepovets", - "Novokuibyševsk", - "Overland Park", - "Novotšerkassk", - "Yuci", - "Kwang-yang", - "Huambo", - "Hengshui", - "Kimberley", - "Guaymas", - "Najafabad", - "Waterbury", - "Najran", - "Xiangtan", - "Pematang Siantar", - "Cairns", - "Papantla", - "Ise", - "Novokuznetsk", - "Kolwezi", - "Bielsko-Biala", - "Jining", - "Macaé", - "Washington", - "Izumisano", - "Higashimurayama", - "Chigasaki", - "Berazategui", - "Gombe", - "Babol", - "Moga", - "Tokuyama", - "Blumenau", - "Laizhou", - "Novosibirsk", - "Warraq al-Arab", - "Klerksdorp", - "Tandil", - "Tepic", - "Balti", - "San Rafael", - "Stahanov", - "Mazatlán", - "Pointe-Noire", - "Kassala", - "Surrey", - "Avellaneda", - "Takasaki", - "Boa Vista", - "San Pedro Cholula", - "Walbrzych", - "Marseille", - "Murwara (Katni)", - "al-Taif", - "Tacna", - "Nicosia", - "Haag", - "Road Town", - "Sheikhupura", - "Phyongsong", - "Düsseldorf", - "Baguio", - "Ixtapaluca", - "Thousand Oaks", - "al-Manama", - "Durham", - "Morena", - "Leiden", - "San Bernardino", - "Tokat", - "Kimchon", - "Scarborough", - "Anyang", - "Frederiksberg", - "Turku [Åbo]", - "San Mateo", - "Florianópolis", - "Machakos", - "Imphal", - "Dagupan", - "Oktjabrski", - "Jacareí", - "Rajahmundry", - "Burgas", - "Banyuwangi", - "Flint", - "Maputo", - "Tieling", - "Reggio di Calabria", - "Oruro", - "Prešov", - "Bender (Tîghina)", - "Cilacap", - "Kirkuk", - "Odessa", - "Mons", - "Pabna", - "Maturín", - "San Martín Texmelucan", - "Khorramshahr", - "Tuguegarao", - "Ovalle", - "Porto Velho", - "Roanoke", - "Iwakuni", - "Niznekamsk", - "Eslamshahr", - "Governador Valadares", - "Mwanza", - "Indianapolis", - "Rewa", - "Port Elizabeth", - "Windhoek", - "Berezniki", - "Des Moines", - "Xiantao", - "Yangquan", - "Sterlitamak", - "Rostock", - "Chinhae", - "Burhanpur", - "Goma", - "Conselheiro Lafaiete", - "Kanchrapara", - "Adana", - "Xianyang", - "Enshi", - "Ikeda", - "Las Palmas de Gran Canaria", - "Corrientes", - "Oulu", - "Pavlodar", - "Andimeshk", - "Nadiad", - "Alkmaar", - "Malkajgiri", - "Köln", - "Guarapuava", - "Asunción", - "Yatsushiro", - "Niterói", - "Phoenix", - "Pimpri-Chinchwad", - "Huzhou", - "Petropavl", - "Bielefeld", - "al-Qatif", - "Lubumbashi", - "Budapest", - "Nizamabad", - "Abha", - "Moradabad", - "Cuautla", - "Dasmariñas", - "Santa Clara", - "Xintai", - "Franco da Rocha", - "Quanzhou", - "Los Teques", - "Sorsogon", - "Sassari", - "Kökshetau", - "Adamstown", - "Anaheim", - "Saint Petersburg", - "Arayat", - "Tultepec", - "Thanjavur", - "Carúpano", - "Brescia", - "Reading", - "Martínez de la Torre", - "Orai", - "Kingstown", - "Northampton", - "Portsmouth", - "Nador", - "Pilar", - "Utsunomiya", - "Tarnów", - "Karbala", - "Faisalabad", - "Monywa", - "Rubtsovsk", - "Ikerre", - "Shizuoka", - "Coquitlam", - "Padova", - "La Rioja", - "Rancho Cucamonga", - "Huainan", - "Allentown", - "Rybnik", - "Geelong", - "Castries", - "Naperville", - "Korhogo", - "Taizz", - "Tumen", - "Zhangzhou", - "Muroran", - "Shreveport", - "Khartum", - "Da´an", - "Aparecida de Goiânia", - "Hisar (Hissar)", - "Kochi", - "Sioux Falls", - "Numazu", - "Uman", - "Linköping", - "Varanasi (Benares)", - "Ibarra", - "Durango", - "Chenzhou", - "Ajmer", - "Betim", - "Santa Monica", - "Nampo", - "Fujin", - "Cabimas", - "Mayagüez", - "Stamford", - "Accra", - "Jamestown", - "Garapan", - "Reggio nell´ Emilia", - "Nawabshah", - "Lianyungang", - "Marl", - "Brasov", - "Praia", - "Lübeck", - "Rio Claro", - "Bayawan (Tulong)", - "Abakan", - "Mudanjiang", - "Göttingen", - "al-Khubar", - "Klaipeda", - "Bislig", - "Porto Alegre", - "Huejutla de Reyes", - "Batangas", - "Kaunas", - "Iloilo", - "Panevezys", - "Mbabane", - "Srinagar", - "Staryi Oskol", - "Mata-Utu", - "Neuss", - "Alvorada", - "Slough", - "George", - "Nyiregyháza", - "Kuching", - "Querétaro", - "San Salvador", - "Resende", - "Agege", - "Ezhou", - "Uji", - "Kunming", - "Ingolstadt", - "Guagua", - "Sanda", - "Zamboanga", - "Monza", - "Angarsk", - "Buga", - "Santana do Livramento", - "Ibirité", - "Pagadian", - "Omaha", - "Dabgram", - "Yichang", - "Matsuyama", - "San Luis", - "Wellington", - "Palermo", - "Arecibo", - "Jiaohe", - "Midland", - "Astrahan", - "Mandya", - "Macapá", - "Hermosillo", - "Tangail", - "Gongziling", - "Matsusaka", - "Thane (Thana)", - "Stockholm", - "Palghat (Palakkad)", - "Dos Hermanas", - "Tripoli", - "Koudougou", - "Curitiba", - "Chittoor", - "Chimalhuacán", - "Yokosuka", - "Dourados", - "São José dos Pinhais", - "Cockburn Town", - "Izmir", - "Bhuj", - "Itu", - "Qaraghandy", - "Jabalpur", - "Syktyvkar", - "Mandasor", - "Eindhoven", - "South Hill", - "Burayda", - "Zhoukou", - "Burgos", - "Rohtak", - "Surat", - "Solingen", - "Gaza", - "Soligorsk", - "Elizabeth", - "Laiwu", - "Montgomery", - "Cincinnati", - "Shuangyashan", - "Nagareyama", - "Liaoyang", - "Taboão da Serra", - "Miyakonojo", - "Uttarpara-Kotrung", - "Puerto Princesa", - "Ottawa", - "Pokhara", - "Madiun", - "Coquimbo", - "Silang", - "Innsbruck", - "Shah Alam", - "Oleksandrija", - "Nouâdhibou", - "Kamoke", - "Pescara", - "Mossoró", - "Knoxville", - "Braga", - "Reykjavík", - "Córdoba", - "Nossa Senhora do Socorro", - "Godhra", - "Asahikawa", - "Wollongong", - "Murmansk", - "Chandrapur", - "Kaesong", - "Stara Zagora", - "Naju", - "Westonaria", - "St Petersburg", - "Puyang", - "Rach Gia", - "Ogaki", - "Ciudad de Panamá", - "Matsue", - "Natal", - "Patan", - "Shivapuri", - "Central Coast", - "Sudbury", - "Vitebsk", - "Banjarmasin", - "Chattanooga", - "Santa Luzia", - "Tampa", - "Nantong", - "El Monte", - "Matsumoto", - "Cosoleacaque", - "Margilon", - "Chittagong", - "Iquitos", - "Wonsan", - "Detroit", - "Getafe", - "Mukatševe", - "Karlsruhe", - "Morvi", - "Nara", - "Gujranwala", - "Zhoushan", - "Yuanjiang", - "Baranovitši", - "Abiko", - "Oldbury/Smethwick (Warley)", - "Rustavi", - "Santiago del Estero", - "Kansas City", - "Valencia", - "Tangerang", - "Ambon", - "Chicago", - "Jacobabad", - "Murom", - "Tsu", - "Raigarh", - "Saint George´s", - "Bandar Seri Begawan", - "Araguari", - "Kampala", - "Pucallpa", - "Moroni", - "Catanzaro", - "Elâzig", - "Jelets", - "Basse-Terre", - "San José del Monte", - "Cusco", - "Ormoc", - "Cagliari", - "Moundou", - "Zhuzhou", - "Dezful", - "Jalna", - "Qandahar", - "Erzurum", - "Omsk", - "Fairfield", - "Cuautitlán Izcalli", - "Hamm", - "Dali", - "Rivne", - "Huizhou", - "Tijuana", - "Almoloya de Juárez", - "Firenze", - "Yongchon", - "Linqing", - "Port-au-Prince", - "Christchurch", - "Namyangju", - "Harkova [Harkiv]", - "El Tigre", - "Cambridge", - "Muzaffargarh", - "Chongjin", - "Terni", - "Xingtai", - "Birmingham", - "Apucarana", - "Blantyre", - "Taonan", - "Xiaoshan", - "Cleveland", - "Damanhur", - "Piacenza", - "Waru", - "Asansol", - "Masaya", - "Mostaganem", - "Xinxiang", - "Túxpam", - "Fuqing", - "São José do Rio Preto", - "Torrejón de Ardoz", - "Shimonoseki", - "Toledo", - "Songnam", - "Yong´an", - "Baoji", - "Bytom", - "al-Hilla", - "Tonk", - "Ratlam", - "Pouso Alegre", - "Concordia", - "San Francisco del Rincón", - "Pak Pattan", - "São Luís", - "Luton", - "Ljubljana", - "La Paz", - "Vallejo", - "Sapucaia do Sul", - "Vitória da Conquista", - "Bansberia", - "Augusta-Richmond County", - "Cumaná", - "Cesena", - "Nantou", - "al-Ayn", - "Lund", - "Tabriz", - "Bremerhaven", - "Patras", - "Kramatorsk", - "Duque de Caxias", - "Ciudad Madero", - "Kaliningrad", - "Coatzacoalcos", - "Graz", - "Calbayog", - "Westminster", - "Jiangmen", - "Fukuoka", - "Maastricht", - "Bawshar", - "Caguas", - "Brazzaville", - "Can Tho", - "Sucre", - "Iwaki", - "Kénitra", - "Cuddalore", - "Kendari", - "Magnitogorsk", - "Ürgenc", - "Suez", - "Lhokseumawe", - "Duran [Eloy Alfaro]", - "Willemstad", - "Sargodha", - "Bijsk", - "Mogiljov", - "Trondheim", - "Fatehpur", - "Kislovodsk", - "Tirana", - "Kyzyl", - "Marbella", - "Loja", - "Mati", - "Tanga", - "Calama", - "Bolton", - "Roodepoort", - "Perpignan", - "Farrukhabad-cum-Fatehgarh", - "Dandong", - "Barakaldo", - "El Jadida", - "Londrina", - "Freetown", - "York", - "Da Nang", - "Nazret", - "Prizren", - "Szeged", - "Umlazi", - "Bahtim", - "Oxnard", - "Soacha", - "Ciudad de Guatemala", - "Jaramana", - "Iseyin", - "Pjatigorsk", - "Tierra Blanca", - "Hazaribag", - "Shangqiu", - "Ferrara", - "Araure", - "San Fernando", - "Urayasu", - "Ludwigshafen am Rhein", - "Ghaziabad", - "Ya´an", - "Matamoros", - "Shillong", - "Copiapó", - "Tanshui", - "Atyrau", - "Pondicherry", - "Yonkers", - "Basirhat", - "Tegal", - "Riverside", - "Sikar", - "Yanji", - "Kagoshima", - "Birigui", - "Constantine", - "Envigado", - "Gatineau", - "Kerman", - "Huancayo", - "Rufisque", - "Guaymallén", - "Salinas", - "Baicheng", - "Rockford", - "Chifeng", - "Sultan Kudarat", - "Wuxi", - "La Ceiba", - "Zinder", - "Campinas", - "Madison", - "Serpuhov", - "Kempton Park", - "Murcia", - "Portland", - "Galati", - "Volgograd", - "Tokai", - "Târgoviste", - "Kermanshah", - "Serra", - "Agra", - "Baruta", - "Yachiyo", - "Kalyan", - "Masqat", - "Banda", - "Zelenograd", - "Gera", - "Tourcoing", - "Karawang", - "Itapecerica da Serra", - "Dashhowuz", - "Sotši", - "Dolores Hidalgo", - "Fresno", - "Rustenburg", - "Pénjamo", - "Urdaneta", - "Joinville", - "Fuji", - "Antsirabé", - "Kunsan", - "Patna", - "Ugep", - "Sharja", - "Bloemfontein", - "Koje", - "Johannesburg", - "Okara", - "Bratislava", - "Yan´an", - "Baoding", - "Ichikawa", - "Chengde", - "Zabrze", - "Yerevan", - "Mbeya", - "Tucheng", - "Jhang", - "Yamato", - "Bozhou", - "Kano", - "Ubon Ratchathani", - "Jacksonville", - "Orša", - "Poza Rica de Hidalgo", - "Wuppertal", - "Nyala", - "Mergui (Myeik)", - "Andijon", - "Vihari", - "al-Faiyum", - "Stockport", - "Katowice", - "Kurnool", - "Annaba", - "Zwickau", - "Huangyan", - "Tokorozawa", - "Qyzylorda", - "Kurashiki", - "Gorgan", - "Morón", - "Nagoya", - "Tonghae", - "Patiala", - "Timkur", - "Maceió", - "Bydgoszcz", - "Naçala-Porto", - "Ciudad Losada", - "Cabuyao", - "Trabzon", - "Popayán", - "Erode", - "Huánuco", - "Hmelnytskyi", - "Chechon", - "Bellary", - "Da Lat", - "Ramagundam", - "Liège", - "Kryvyi Rig", - "Rabat", - "Delmas", - "Bhagalpur", - "Meihekou", - "Dindigul", - "Kohat", - "Sittwe (Akyab)", - "Tanza", - "Cartagena", - "Wiesbaden", - "Haicheng", - "Toyama", - "A Coruña (La Coruña)", - "Jessentuki", - "Shahrud", - "Bally", - "Merlo", - "Yamagata", - "Ila", - "Raipur", - "Resistencia", - "Huaying", - "Barrie", - "Castellón de la Plana [Castell", - "Rishra", - "Clermont-Ferrand", - "Oyo", - "Divinópolis", - "Bandar-e Anzali", - "Chatsworth", - "Haeju", - "São Tomé", - "Diourbel", - "Bonn", - "Daito", - "Salvatierra", - "Silchar", - "Zhongshan", - "Paju", - "Kumamoto", - "Tegucigalpa", - "Durban", - "Cape Coral", - "Tirunelveli", - "Arrah (Ara)", - "General San Martín", - "Dar es Salaam", - "Zhangjiang", - "Pallavaram", - "Nashville-Davidson", - "Ancona", - "Lexington-Fayette", - "Mathura", - "São Bernardo do Campo", - "Granada", - "Rotterdam", - "Genova", - "Saanich", - "Mandi Burewala", - "Ilan", - "Gulbarga", - "Orenburg", - "Fujinomiya", - "Hyesan", - "Saint-Louis", - "El Fuerte", - "Arlington", - "Ventanilla", - "Guadalajara", - "Jelenia Góra", - "Roxas", - "Malvinas Argentinas", - "Banda Aceh", - "Rio Branco", - "Holguín", - "Shiraz", - "Rae Bareli", - "Fukui", - "Kamakura", - "Satara", - "Depok", - "Maracanaú", - "Aachen", - "Campeche", - "San Miguel", - "Kota Bharu", - "Salzburg", - "Sundsvall", - "Arvada", - "Duma", - "Campo Largo", - "Bratsk", - "Abu Dhabi", - "Allende", - "Ulsan", - "Mamoutzou", - "Bose", - "Tacloban", - "Schaerbeek", - "Agadir", - "Barretos", - "Gonda", - "Taiping", - "Marikina", - "Wazirabad", - "Boulogne-Billancourt", - "Wonderboom", - "Gilbert", - "Circik", - "Castanhal", - "Manila", - "Sevilla", - "Medellín", - "Navoi", - "Delta", - "Pingtung", - "Tsukuba", - "Nilópolis", - "Thimphu", - "Atibaia", - "Santa Cruz do Sul", - "Xuchang", - "Puerto Montt", - "Neiva", - "Ede", - "Hsinchuang", - "Bauru", - "Chaguanas", - "Pekalongan", - "[San Cristóbal de] la Laguna", - "Narita", - "Shijiazhuang", - "Latina", - "Offa", - "Langfang", - "Cangzhou", - "Salé", - "Lapu-Lapu", - "Saint John´s", - "Pingchen", - "Herson", - "Livorno", - "Jaunpur", - "Cimahi", - "Sabzevar", - "Sultanbeyli", - "Awka", - "Itaquaquecetuba", - "Dujiangyan", - "Libreville", - "Maicao", - "Veliki Novgorod", - "Cachoeirinha", - "Konya", - "Tlemcen (Tilimsen)", - "Kusti", - "Krugersdorp", - "Long Beach", - "Ji-Paraná", - "Culiacán", - "Bahir Dar", - "Peterborough", - "Campina Grande", - "Hail", - "Tunja", - "Yantai", - "Vijayawada", - "Bat Yam", - "Bidar", - "Glazov", - "Nakhon Ratchasima", - "Mingora", - "Mulhouse", - "Khomeynishahr", - "al-Mahallat al-Kubra", - "Nuuk", - "Sialkot", - "Ome", - "Miass", - "Zhaodong", - "Santa Rita", - "Djibouti", - "Weifang", - "Maebashi", - "Nasugbu", - "Aracaju", - "Fushun", - "Gäncä", - "Hatay (Antakya)", - "N´Djaména", - "Namibe", - "Camaragibe", - "Dese", - "Jaipur", - "Gurgaon", - "Osmaniye", - "Biratnagar", - "Jalandhar (Jullundur)", - "Sorocaba", - "Baghdad", - "Iksan", - "Split", - "Ústí nad Labem", - "Ulan-Ude", - "al-Najaf", - "Kimhae", - "Karsi", - "Slovjansk", - "Laval", - "Saarbrücken", - "Trento", - "Mutare", - "Nagasaki", - "Ilorin", - "Liangcheng", - "Shimizu", - "Garanhuns", - "Tema", - "Sosan", - "Krasnogorsk", - "Ningbo", - "Alcalá de Henares", - "Hualien", - "Carmen", - "Ciudad de México", - "Posadas", - "Uppsala", - "Bukan", - "San Felipe de Puerto Plata", - "Vorkuta", - "Callao", - "Bento Gonçalves", - "Bida", - "Dalap-Uliga-Darrit", - "Sayama", - "Riga", - "Jamalpur", - "Mesquite", - "Beni-Mellal", - "Ariana", - "Kimitsu", - "Zhangjiakou", - "Jaraguá do Sul", - "Viamão", - "Zukovski", - "Muzaffarnagar", - "Chishtian Mandi", - "Pusan", - "Delhi Cantonment", - "Salvador", - "Taguig", - "Yangjiang", - "Tšita", - "Kaohsiung", - "Khanewal", - "Rjazan", - "Beerseba", - "Nakhon Pathom", - "Bhiwandi", - "Majalaya", - "Vereeniging", - "Coventry", - "Miskolc", - "Karaman", - "Kolomna", - "Venezia", - "Barueri", - "Noida", - "Springs", - "Khairpur", - "Qutubullapur", - "Salem", - "Iquique", - "Ahome", - "Ilawe-Ekiti", - "Subotica", - "Santa Cruz de Tenerife", - "Saratov", - "Niamey", - "Kiel", - "Qingzhou", - "Mishan", - "Angren", - "Brockton", - "Toa Baja", - "Dadu", - "Winston-Salem", - "Chisinau", - "Selayang Baru", - "Semnan", - "Zenica", - "Metairie", - "Coimbatore", - "Honolulu", - "San Nicolás de los Garza", - "Panihati", - "Cunduacán", - "Ganganagar", - "Bhavnagar", - "Jiaozhou", - "Billings", - "Hohhot", - "Valparaíso", - "Armavir", - "Maracay", - "Idfu", - "Kathmandu", - "Kandy", - "Saint-Pierre", - "Taxco de Alarcón", - "Nowshera", - "Salala", - "Miryang", - "Shishou", - "Ussurijsk", - "Gelsenkirchen", - "Watford", - "Cluj-Napoca", - "al-Qamishliya", - "Kuwait", - "Mysore", - "Manukau", - "Waco", - "Shizuishan", - "Sabará", - "Giugliano in Campania", - "Nairobi", - "Osh", - "Uljanovsk", - "Cachoeiro de Itapemirim", - "Lahti", - "Alcorcón", - "Phnom Penh", - "Würzburg", - "Mardan", - "Bobo-Dioulasso", - "Bangalore", - "Santa Cruz", - "Norilsk", - "Hodeida", - "Vidisha", - "Soweto", - "Tokushima", - "Macon", - "Guilin", - "Meerut", - "Asmara", - "Bilbao", - "Florencio Varela", - "Amroha", - "El Limón", - "Thiruvananthapuram (Trivandrum", - "Algeciras", - "Dallas", - "Port-of-Spain", - "Lowell", - "Uruguaiana", - "Zhucheng", - "Little Rock", - "Kananga", - "Votorantim", - "Ichalkaranji", - "Lambaré", - "Onomichi", - "Ondo", - "Manzhouli", - "Chiba", - "Schaan", - "Handan", - "Nanking [Nanjing]", - "Ueda", - "Centro (Villahermosa)", - "Pireus", - "Tampico", - "Machilipatnam (Masulipatam)", - "Lancaster", - "Sungai Petani", - "Sete Lagoas", - "Newport News", - "Xichang", - "Malita", - "Concord", - "Zamora", - "Candelaria", - "Luoyang", - "Teresópolis", - "Touliu", - "Worcester", - "Beaumont", - "Reims", - "Acámbaro", - "Ambala", - "Formosa", - "Quezon", - "Barra do Piraí", - "al-Hufuf", - "Brahmanbaria", - "Tambov", - "Lower Hutt", - "Damoh", - "Wroclaw", - "Denpasar", - "Limeira", - "Kielce", - "Strasbourg", - "Muzaffarpur", - "Belize City", - "Modesto", - "Moratuwa", - "Vientiane", - "Warszawa", - "Malolos", - "Wanxian", - "Vinnytsja", - "Bayamo", - "Aalborg", - "Osasco", - "Mezduretšensk", - "Igboho", - "Iwatsuki", - "Temapache", - "Roma", - "Kingston upon Hull", - "Emmen", - "Bhusawal", - "Hugli-Chinsurah", - "Khoy", - "Bayamón", - "Mabalacat", - "Khorramabad", - "Zaragoza", - "Alofi", - "Pittsburgh", - "Ituzaingó", - "Beihai", - "Bengbu", - "Potchefstroom", - "Columbus", - "Wolfsburg", - "Damascus", - "Nizni Tagil", - "Darmstadt", - "Bantam", - "La Serena", - "Nyeri", - "Cape Town", - "Pondokgede", - "Hiratsuka", - "Fukuyama", - "Bristol", - "Araguaína", - "Tangshan", - "Bogra", - "Amiens", - "Buenaventura", - "Yiyang", - "Chonan", - "Epe", - "Apeldoorn", - "Tlaquepaque", - "Itaituba", - "Lecce", - "Phan Thiêt", - "Nishinomiya", - "Calamba", - "Coronel Fabriciano", - "Zwolle", - "Oral", - "Oujda", - "Shantou", - "Vologda", - "Székesfehérvár", - "Tsaotun", - "Vicente López", - "Akure", - "Münster", - "Tiruvannamalai", - "Grudziadz", - "Guangshui", - "Kakamigahara", - "Tomakomai", - "Schwerin", - "Dili", - "Öskemen", - "Taranto", - "Barahanagar (Baranagar)", - "La Matanza", - "Basildon", - "Araras", - "Xuzhou", - "Hidalgo del Parral", - "Andong", - "Diadema", - "Shiyan", - "Durg", - "Helsingborg", - "Pinar del Río", - "Maragheh", - "Bridgeport", - "Sukkur", - "Zaporizzja", - "Shihung", - "Bokaro Steel City", - "Suita", - "Bari", - "Teixeira de Freitas", - "Kimchaek", - "Tallahassee", - "Tanta", - "Oshogbo", - "Sanming", - "Mülheim an der Ruhr", - "Pueblo", - "Ibagué", - "Heidelberg", - "Sanya", - "Ayacucho", - "Tiruvottiyur", - "Lida", - "Erlangen", - "Papeete", - "Kinešma", - "Kirovo-Tšepetsk", - "Arnhem", - "Lipa", - "Mitšurinsk", - "Hurlingham", - "Laredo", - "Tulancingo de Bravo", - "Bojnurd", - "Krishnanagar", - "Jaroslavl", - "Binzhou", - "Birjand", - "Bobruisk", - "Boise City", - "Iasi", - "Stoke-on-Trent", - "Yokkaichi", - "Spokane", - "Sakai", - "Ciomas", - "Curicó", - "Erfurt", - "Multan", - "Kasuga", - "Peristerion", - "Mitaka", - "Novyi Urengoi", - "Neftejugansk", - "Jenakijeve", - "Groningen", - "Ica", - "Jombang", - "Botucatu", - "Macao", - "Panipat", - "Gomel", - "Sunchon", - "Ribeirão Pires", - "Beipiao", - "al-Fashir", - "Tirupati", - "Udon Thani", - "Halifax", - "Newcastle upon Tyne", - "Douglas", - "Les Abymes", - "San Francisco de Macorís", - "Jerez de la Frontera", - "Stavropol", - "Olmalik", - "Valledupar", - "al-Salimiya", - "Uzgorod", - "Bharatpur", - "Southend-on-Sea", - "Acarigua", - "Qingyuan", - "Hapur", - "Dimitrovgrad", - "Sonipat (Sonepat)", - "Palmas", - "Kamjanets-Podilskyi", - "Århus", - "Los Cabos", - "Chärjew", - "Sacramento", - "Puqi", - "Ciudad Guayana", - "Grodno", - "Camaçari", - "Zeleznodoroznyi", - "Liaoyuan", - "Ndola", - "Apia", - "Pasuruan", - "Passo Fundo", - "Fullerton", - "Ciputat", - "Braila", - "Ponta Grossa", - "Toyota", - "Suzano", - "Paradise", - "Harare", - "Valera", - "Bhilwara", - "Gorzów Wielkopolski", - "Inisa", - "Satna", - "Bacolod", - "Szczecin", - "Malaybalay", - "Guaynabo", - "Inegöl", - "Inchon", - "Qitaihe", - "Batumi", - "Novorossijsk", - "Augsburg", - "Charlotte", - "Oxford", - "Kingston", - "Okayama", - "Madrid", - "Pretoria", - "Oslo", - "Pervouralsk", - "Hargeysa", - "Yogyakarta", - "Qianjiang", - "Barranquilla", - "Sawangan", - "Peshawar", - "Wardha", - "Asan", - "Fremont", - "Tuluá", - "Burlington", - "Irbil", - "Lafia", - "Jaú", - "Nabereznyje Tšelny", - "Praha", - "Pasay", - "Fuyang", - "São José", - "Jedda", - "Sancti-Spíritus", - "Uluberia", - "Huai´an", - "Reno", - "Yamuna Nagar", - "Baybay", - "Aizuwakamatsu", - "Daloa", - "Kodaira", - "Barletta", - "Bhiwani", - "Witten", - "Bushehr", - "José C. Paz", - "Dnipropetrovsk", - "Probolinggo", - "Bikenibeu", - "Oceanside", - "Batna", - "Jiangyin", - "Astana", - "Hartford", - "Mangalore", - "al-Arish", - "Sarapul", - "Karimnagar", - "Alger", - "Cilegon", - "Semey", - "Tigre", - "Chandler", - "Toulon", - "Hoshiarpur", - "Shenzhen", - "Osorno", - "Shikarpur", - "Ipoh", - "Banja Luka", - "Narsinghdi", - "Gejiu", - "Itapevi", - "Funafuti", - "Gent", - "Komsomolsk-na-Amure", - "Lahore", - "Dobric", - "Parañaque", - "Allahabad", - "Navsari", - "Seoul", - "Pyongtaek", - "Obeid", - "Apopa", - "Norrköping", - "Amman", - "Xilin Hot", - "Kure", - "Lisboa", - "Heerlen", - "Abottabad", - "Hirosaki", - "Takatsuki", - "Tekirdag", - "Danjiangkou", - "Palu", - "Irkutsk", - "Moreno Valley", - "Thai Nguyen", - "Kassel", - "Shaoxing", - "Bakersfield", - "Pforzheim", - "Jinxi", - "Peoria", - "Imperatriz", - "Pali", - "Vellore", - "Oran", - "Rancagua", - "Témara", - "Ciudad Valles", - "Kansk", - "Anjo", - "Saskatoon", - "Mexico", - "Kitwe", - "Zaozhuang", - "Mango", - "Columbia", - "Mauá", - "Yungkang", - "Mar del Plata", - "Kyongsan", - "Brjansk", - "Benguela", - "Hiroshima", - "Melbourne", - "Sachon", - "Henzada (Hinthada)", - "Teresina", - "Kharagpur", - "Banjul", - "Mytištši", - "Iligan", - "Enugu", - "Nigel", - "Elche [Elx]", - "Patos", - "Weihai", - "Arzamas", - "Port Sudan", - "Qidong", - "Tianjin", - "Thessaloniki", - "Guiyang", - "Ciparay", - "Mozyr", - "Bandar-e-Abbas", - "Ordu", - "Skopje", - "Koronadal", - "Luxembourg [Luxemburg/Lëtzebuerg]", - "Guaratinguetá", - "Le Havre", - "Juazeiro", - "Wuwei", - "Grand Rapids", - "Bukavu", - "George Town", - "Cauayan", - "Derbent", - "Bournemouth", - "Yaizu", - "Carrollton", - "Aydin", - "Bengasi", - "Pingxiang", - "Bremen", - "Mallawi", - "Changzhi", - "Hamadan", - "Tanger", - "Santa Fé", - "Parnamirim", - "Sibiu", - "Vicenza", - "Danao", - "Gabès", - "Poá", - "Nueva San Salvador", - "Burbank", - "Irbid", - "Nassau", - "Bangkok", - "Yangmei", - "Manchester", - "Lafayette", - "Acapulco de Juárez", - "al-Hawiya", - "Xuangzhou", - "Belfast", - "Gijón", - "São José de Ribamar", - "Le Mans", - "Tiruppur (Tirupper)", - "Taza", - "Paramaribo", - "Linchuan", - "San Andrés Tuxtla", - "Pembroke Pines", - "Barbacena", - "Nantes", - "Santa Catarina", - "Chitungwiza", - "Balakovo", - "Hebi", - "Binangonan", - "Rudnyy", - "San Pedro", - "Perm", - "Holon", - "Štšolkovo", - "Miraj", - "Haifa", - "Qazvin", - "Wichita Falls", - "Rybinsk", - "Podgorica", - "Shagamu", - "Temirtau", - "Sharq al-Nil", - "Cochabamba", - "Indore", - "Guna", - "Ratingen", - "Bhopal", - "Costa Mesa", - "Huaibei", - "Nevinnomyssk", - "Taoyuan", - "Zibo", - "Neuquén", - "Oranjestad", - "Vladimir", - "Kumagaya", - "Salta", - "Lubao", - "Brahmapur", - "Paderborn", - "Hartlepool", - "Villeurbanne", - "Rochester", - "Neyshabur", - "Fort Lauderdale", - "Palikir", - "Carson", - "Tainan", - "Morogoro", - "Santiago de los Caballeros", - "Khon Kaen", - "Novi Sad", - "Guntakal", - "Xalapa", - "Contagem", - "Vadodara (Baroda)", - "Ujung Pandang", - "Criciúma", - "Jacobina", - "Bochum", - "Butuan", - "Barddhaman (Burdwan)", - "Jiaozuo", - "Sakata", - "Mainz", - "Gwalior", - "Norman", - "Blackburn", - "Fort-de-France", - "Tšaikovski", - "Jiangyou", - "Changsha", - "Tiaret", - "Latakia", - "Tanauan", - "Braunschweig", - "Neyveli", - "Sunderland", - "Kilis", - "Addis Abeba", - "Monaco-Ville", - "Hanoi", - "East York", - "Parakou", - "Tsuruoka", - "Vitória", - "Santo André", - "Quetzaltenango", - "Jubayl", - "Unnao", - "Moriguchi", - "Khujand", - "Esmeraldas", - "Cuiabá", - "Parma", - "Atlanta", - "Ageo", - "Mingäçevir", - "Donetsk", - "Danyang", - "Taldyqorghan", - "Aligarh", - "Çorlu", - "Nanning", - "Sumy", - "San Miguelito", - "Narayanganj", - "New Haven", - "Balašov", - "Salavat", - "Ploiesti", - "Mersin (Içel)", - "Meerut Cantonment", - "Mekele", - "Bujumbura", - "Bucaramanga", - "Marrakech", - "Yungho", - "Port-Vila", - "Oviedo", - "Santiago de Compostela", - "Rangpur", - "Varna", - "Taipei", - "Minneapolis", - "Kushiro", - "Tšeljabinsk", - "Oshawa", - "Dundee", - "Markham", - "Lima", - "Brampton", - "Boksburg", - "Colorado Springs", - "St-Étienne", - "Regina", - "Randfontein", - "Koblenz", - "Kurgan", - "Shambajinagar (Aurangabad)", - "Fernando de la Mora", - "Otsu", - "Jalib al-Shuyukh", - "Rui´an", - "Kudus", - "Mariupol", - "Mykolajiv", - "Moreno", - "Khulna", - "Béjaïa", - "Nonsan", - "Mataram", - "Louisville", - "Rahim Yar Khan", - "Haiphong", - "Enschede", - "Palmira", - "Apodaca", - "Elektrostal", - "Amarillo", - "Barnaul", - "Zacatecas", - "Halisahar", - "Nottingham", - "Pondok Aren", - "al-Minya", - "Mianyang", - "Benoni", - "Cascavel", - "Almere", - "Baia Mare", - "Morioka", - "São Paulo", - "Zapopan", - "Cuddapah", - "Bahía Blanca", - "Fuyu", - "Saint Helens", - "Tacoma", - "Czestochowa", - "Suizhou", - "San Miguel de Tucumán", - "Rijeka", - "Suwon", - "Zixing", - "Obninsk", - "Paulo Afonso", - "Magadan", - "São Gonçalo", - "Delft", - "Ourinhos", - "Naogaon", - "Kanggye", - "Jekaterinburg", - "Magé", - "Cebu", - "Votkinsk", - "Biñan", - "Lomas de Zamora", - "Panabo", - "Kostroma", - "Kisumu", - "Aix-en-Provence", - "Guarulhos", - "Ilesha", - "Craiova", - "Kanton [Guangzhou]", - "Gaborone", - "Thunder Bay", - "Pachuca de Soto", - "Nanchang", - "Jember", - "Charlotte Amalie", - "Bacabal", - "Musashino", - "Lucena", - "Witbank", - "Kongju", - "Bulawayo", - "Chilpancingo de los Bravo", - "Ibaraki", - "Jinzhou", - "Clarksville", - "Honghu", - "Gravataí", - "Taiyuan", - "Yueyang", - "Izmajil", - "Mönchengladbach", - "Ashikaga", - "Alandur", - "Makurdi", - "Târgu Jiu", - "Queimados", - "Talcahuano", - "Chesapeake", - "Munger (Monghyr)", - "Soledad", - "Guacara", - "Warangal", - "Nanping", - "Berdytšiv", - "Kertš", - "Dos Quebradas", - "Várzea Grande", - "Soyapango", - "Changhwa", - "Leiyang", - "Beawar", - "Kursk", - "Sunnyvale", - "Luanda", - "Sergijev Posad", - "Visalia", - "Isesaki", - "Jequié", - "Inglewood", - "Padang", - "Laoag", - "Caucaia", - "Kwangju", - "Sanaa", - "Jiutepec", - "Othón P. Blanco (Chetumal)", - "Adelaide", - "Marília", - "Ashgabat", - "Junan", - "Drobeta-Turnu Severin", - "Iskenderun", - "Sibu", - "Anqing", - "São João de Meriti", - "Ebina", - "Usolje-Sibirskoje", - "Plock", - "Ahmedabad", - "Canoas", - "Mushin", - "Siem Reap", - "Jaya Pura", - "Agaña", - "Mumbai (Bombay)", - "Matola", - "Coímbra", - "Liverpool", - "Debrecen", - "Birgunj", - "Ongole", - "Angeles", - "New Bombay", - "Chemnitz", - "Beppu", - "Bilaspur", - "Abuja", - "São José dos Campos", - "Jiaonan", - "Nishio", - "Soledad de Graciano Sánchez", - "New Delhi", - "Davao", - "Balikesir", - "Itajaí", - "Komaki", - "Zumpango", - "Kurume", - "Basseterre", - "Aden", - "San Lorenzo", - "Xinzhou", - "Riyadh", - "Dehri", - "Mahatškala", - "Weinan", - "Honiara", - "San Juan del Río", - "Kumbakonam", - "Diyarbakir", - "Fengcheng", - "Isehara", - "Qaemshahr", - "Bradford", - "Sakarya (Adapazari)", - "Longyan", - "Alanya", - "Santa Cruz de la Sierra", - "Koszalin", - "Lansing", - "Aomori", - "Tamale", - "North Las Vegas", - "Ulanhot", - "Mombasa", - "Izumi", - "La Plata", - "Puente Alto", - "Percut Sei Tuan", - "Rangoon (Yangon)", - "Caxias", - "Pune", - "Maiduguri", - "Amsterdam", - "Pyongyang", - "Xining", - "Meikhtila", - "Kashiwa", - "Gaziantep", - "Taunggyi (Taunggye)", - "Hakodate", - "Stockton", - "al-Qadarif", - "Kwangmyong", - "Hangzhou", - "Osnabrück", - "Zagazig", - "Zhuhai", - "Daqing", - "Tongling", - "Ji´an", - "Birkenhead", - "Cartago", - "Proddatur", - "Irving", - "Aqsu", - "Jhansi", - "Puerto La Cruz", - "Southport", - "Ambato", - "Armenia", - "Vladikavkaz", - "Tampere", - "Chapecó", - "Tychy", - "Tuticorin", - "Liaocheng", - "Malungon", - "Teheran", - "Gadag Betigeri", - "Hongjiang", - "Santa Bárbara d´Oeste", - "Lleida (Lérida)", - "Siirt", - "Orehovo-Zujevo", - "Paarl", - "Belgorod", - "Dresden", - "Gillingham", - "Indaiatuba", - "Vila Velha", - "Jastrzebie-Zdrój", - "Yingkou", - "Ponce", - "Hortolândia", - "Toljatti", - "Provo", - "Vizianagaram", - "Yumen", - "Tšeboksary", - "Darbhanga", - "Constanta", - "Guadalupe", - "Mazar-e-Sharif", - "Kangshan", - "Xiangfan", - "Wenzhou", - "Shimoga", - "Tula", - "Nellore", - "Siliguri (Shiliguri)", - "Linz", - "Larkana", - "Leeds", - "San Luis Río Colorado", - "Bolzano", - "Velbert", - "Deyang", - "Sétif", - "Glendale", - "Brighton", - "Kahramanmaras", - "Iida", - "Mahabad", - "Concepción", - "Ivano-Frankivsk", - "San Marino", - "Berlin", - "Tabaco", - "Catanduva", - "Bareilly", - "São Lourenço da Mata", - "Hubli-Dharwad", - "Celaya", - "Edinburgh", - "Piracicaba", - "Blagoveštšensk", - "Toda", - "Le-Cap-Haïtien", - "Xinyang", - "Kanazawa", - "Irapuato", - "Minoo", - "Bogor", - "Kiziltepe", - "Sidi Bel Abbès", - "Hsintien", - "Pingliang", - "Soshanguve", - "Ferraz de Vasconcelos", - "Changzhou", - "Port-Louis", - "Donostia-San Sebastián", - "Owo", - "Gandhinagar", - "Cairo", - "Bhatinda (Bathinda)", - "Gold Coast", - "Berdjansk", - "Santander", - "Cedar Rapids", - "Itabira", - "Savannakhet", - "Karaj", - "Bilbays", - "Recklinghausen", - "Anchorage", - "Fengyuan", - "Norfolk", - "Kunshan", - "Dubai", - "San Bernardo", - "Nicolás Romero", - "Edmonton", - "Jaffna", - "Eunápolis", - "Lianyuan", - "Hagonoy", - "al-Mukalla", - "Gdansk", - "Anzero-Sudzensk", - "Fujieda", - "al-Sulaymaniya", - "Midsayap", - "Clearwater", - "Kumi", - "Agartala", - "Arad", - "Valparai", - "Torrance", - "Tokyo", - "Luzhou", - "Sheffield", - "Plymouth", - "Ibb", - "Cuenca", - "Bila Tserkva", - "Windsor", - "Kelowna", - "Ezeiza", - "Toamasina", - "Gojra", - "Biserta", - "Sunrise Manor", - "Águas Lindas de Goiás", - "Bataisk", - "Vacoas-Phoenix", - "Manado", - "Ontario", - "Arezzo", - "Andria", - "Karnal", - "Longjing", - "Sanchung", - "Arusha", - "Jirja", - "Hat Yai", - "Mahbubnagar", - "Cavite", - "Kawanishi", - "Bassein (Pathein)", - "Kinshasa", - "Raurkela Civil Township", - "Nancy", - "Naha", - "Kabul", - "Hathras", - "Remscheid", - "Ranchi", - "Oberholzer", - "Linhai", - "Araçatuba", - "Osijek", - "Balikpapan", - "Kragujevac", - "Béchar", - "Grand Prairie", - "Naucalpan de Juárez", - "Dalian", - "Lünen", - "Chonju", - "Gandhidham", - "Naga", - "Kukatpalle", - "Katihar", - "Linhe", - "Ludhiana", - "Juba", - "Ikare", - "San Pedro Garza García", - "Huangshi", - "Punta Arenas", - "Suhar", - "Escobar", - "Itabuna", - "Wafangdian", - "Taegu", - "Colatina", - "Jamnagar", - "Kumasi", - "Pilibhit", - "Rafsanjan", - "Abaetetuba", - "Vladivostok", - "Monrovia", - "Himeji", - "Fianarantsoa", - "Kitami", - "Ensenada", - "Kemerovo", - "Mejicanos", - "Rzeszów", - "Cabanatuan", - "Mufulira", - "Tieli", - "Chula Vista", - "Pamplona [Iruña]", - "Buenos Aires", - "Purnea (Purnia)", - "Woking/Byfleet", - "Zlatoust", - "San Cristóbal de las Casas", - "Bergamo", - "Sosnowiec", - "São Carlos", - "Quito", - "Tong Xian", - "Borisov", - "Delicias", - "Joetsu", - "Neftekamsk", - "Vantaa", - "Islamabad", - "Iruma", - "Bago", - "Nepean", - "Bologna", - "Pietermaritzburg", - "Hsichuh", - "Gävle", - "Nizni Novgorod", - "Eldoret", - "Bruxelles [Brussel]", - "Comodoro Rivadavia", - "Saint Catharines", - "Montevideo", - "Rouen", - "Muntinlupa", - "Linyi", - "Västerås", - "Chaozhou", - "Habra", - "Afyon", - "Timon", - "Ulm", - "Mannheim", - "Vitória de Santo Antão", - "Rasht", - "Achalpur", - "Skikda", - "Dezhou", - "Kirovograd", - "Suva", - "Garden Grove", - "Mira Bhayandar", - "Khan Yunis", - "Engels", - "Wuzhou", - "Leshan", - "Kelang", - "Kikwit", - "Cajeme", - "Gonder", - "Tomsk", - "Hachioji", - "Móstoles", - "Shymkent", - "Huddersfield", - "Kamensk-Uralski", - "Orizaba", - "Leverkusen", - "Anshan", - "Québec", - "Neyagawa", - "Bhatpara", - "Caxias do Sul", - "Juzno-Sahalinsk", - "Zonguldak", - "Apatzingán", - "Secunderabad", - "Hachinohe", - "Huangshan", - "Mojokerto", - "Lerdo", - "Aqtau", - "Hoya", - "Serravalle", - "Guatire", - "Bandung", - "Yonezawa", - "Hsinchu", - "Malasiqui", - "Belo Horizonte", - "Barasat", - "North Shore", - "Antananarivo", - "Trieste", - "Sofija", - "Shangrao", - "Gjumri", - "Slupsk", - "Shanwei", - "Poole", - "Shashi", - "Maizuru", - "Pelotas", - "Miaoli", - "Malayer", - "Hollywood", - "Samarinda", - "Cary", - "Uhta", - "Hindupur", - "Klaten", - "Beograd", - "Plzen", - "Kulti-Barakar", - "Ishinomaki", - "Brakpan", - "New York", - "Hefei", - "Araraquara", - "Xingcheng", - "Las Vegas", - "Tabuk", - "Chorzów", - "Santa Marta", - "Rishon Le Ziyyon", - "Mosul", - "Yeotmal (Yavatmal)", - "Legazpi", - "Ostrava", - "Ciego de Ávila", - "Tehuacán", - "Kofu", - "Mandaluyong", - "al-Hawamidiya", - "Ciudad Bolívar", - "Larisa", - "Calabar", - "Ambattur", - "Buffalo", - "Leipzig", - "Wendeng", - "Bafoussam", - "Lázaro Cárdenas", - "Monte-Carlo", - "Baliuag", - "Hardwar (Haridwar)", - "Qaramay", - "Wichita", - "Haikou", - "Port Said", - "Taganrog", - "Saqqez", - "Welkom", - "Santafé de Bogotá", - "San Juan del Monte", - "Dhanbad", - "Dehiwala", - "Istanbul", - "Cirebon", - "Dudley", - "Porto", - "Zürich", - "Dhule (Dhulia)", - "Beau Bassin-Rose Hill", - "Herat", - "Bismil", - "Rafah", - "Montpellier", - "Barrancabermeja", - "Kirov", - "Gliwice", - "Yushu", - "Palembang", - "Walsall", - "Narashino", - "Namur", - "Khuzdar", - "Etawah", - "Tsuchiura", - "Charleston", - "Rajshahi", - "Itagüí", - "Angers", - "Sogamoso", - "Quelimane", - "Ech-Chleff (el-Asnam)", - "Santa Ana de Coro", - "Keelung (Chilung)", - "Baiyin", - "Lysytšansk", - "Daraga (Locsin)", - "Presidente Prudente", - "Kiryu", - "Recife", - "Pegu (Bago)", - "Kolhapur", - "Malabo", - "Fuxin", - "Batam", - "São Leopoldo", - "Jinan", - "Cixi", - "Karabük", - "Athenai", - "Zaoyang", - "Chiniot", - "Catia La Mar", - "Jincheng", - "Smolensk", - "Ksar el Kebir", - "Tarlac", - "Tel Aviv-Jaffa", - "Managua", - "Swindon", - "Guigang", - "Lalbahadur Nagar", - "Santos", - "Sydney", - "Atsugi", - "Liling", - "Calicut (Kozhikode)", - "Sasaram", - "Paraná", - "Hialeah", - "Acuña", - "Kafr al-Dawwar", - "Winnipeg", - "Atšinsk", - "Samsun", - "Ganzhou", - "Lomé", - "Niiza", - "Juiz de Fora", - "Liyang", - "Pingdingshan", - "Nürnberg", - "Kunpo", - "Rio Verde", - "Puerto Vallarta", - "al-Zawiya", - "Salzgitter", - "Xi´an", - "Zigong", - "Koror", - "Tucson", - "Bairiki", - "Barra Mansa", - "Yinchuan", - "Florencia", - "Fuenlabrada", - "Oradea", - "Disuq", - "Cayenne", - "Omiya", - "Pasadena", - "Beirut", - "Cuauhtémoc", - "Haarlem", - "Qinzhou", - "San Luis de la Paz", - "Cariacica", - "Huixquilucan", - "Ankang", - "Yizheng", - "Koriyama", - "Tonghua", - "Malatya", - "Yongju", - "Orléans", - "Tallinn", - "Brindisi", - "Sumaré", - "Tajimi", - "Raiganj", - "Nikopol", - "Zytomyr", - "Santiago Ixcuintla", - "Cam Ranh", - "Ljubertsy", - "Bhimavaram", - "Benin City", - "Heilbronn", - "Unayza", - "Tasikmalaya", - "Sukabumi", - "Auckland", - "Sasebo", - "Sanliurfa", - "Sanandaj", - "East Los Angeles", - "Tengzhou", - "Botosani", - "Guelph", - "Bissau", - "Tulsa", - "Pinetown", - "Gusau", - "Quetta", - "Bhilai", - "Juazeiro do Norte", - "Suzuka", - "Kecskemét", - "Jodhpur", - "Duyun", - "Korla", - "Viña del Mar", - "Quzhou", - "Budaun", - "Nablus", - "Chennai (Madras)", - "Bouaké", - "Sahiwal", - "Zitácuaro", - "Anantapur", - "Iserlohn", - "Punto Fijo", - "Torre del Greco", - "Fakaofo", - "Basel", - "Omdurman", - "Middlesbrough", - "Oklahoma City", - "Luohe", - "Gothenburg [Göteborg]", - "Cizah", - "Lalitapur", - "Haining", - "Soka", - "Puškin", - "Qingdao", - "Guntur", - "Fès", - "Seattle", - "Khandwa", - "Hampton", - "Higashihiroshima", - "Kaolack", - "Taraz", - "Qalyub", - "Volta Redonda", - "Siping", - "Nezahualcóyotl", - "Namwon", - "Pánuco", - "Yazd", - "Puerto Cabello", - "Oldham", - "Miyazaki", - "Ust-Ilimsk", - "Petrolina", - "Harbin", - "Sariaya", - "Xinyu", - "Abbotsford", - "Torun", - "Tete", - "Bharuch (Broach)", - "Saint-Denis", - "Tšernigiv", - "Changde", - "Modena", - "Tebing Tinggi", - "Sandy", - "Cibinong", - "Valle de la Pascua", - "Ise-Ekiti", - "Montreuil", - "Toyohashi", - "Gary", - "Waitakere", - "Fargona", - "Uvira", - "Laiyang", - "Nagar Coil", - "Ara´ar", - "al-Mubarraz", - "Šahty", - "Manta", - "Seremban", - "Chhindwara", - "Arapiraca", - "Caen", - "Novopolotsk", - "Esteban Echeverría", - "Niznevartovsk", - "Sutton Coldfield", - "Chang-won", - "Munich [München]", - "Tšerkasy", - "Nanchong", - "Biskra", - "Cotabato", - "Cainta", - "Velikije Luki", - "Hue", - "Esslingen am Neckar", - "Toyokawa", - "Raleigh", - "Padang Sidempuan", - "Chungju", - "Bhir (Bid)", - "Terrassa", - "Valladolid", - "Andorra la Vella", - "Shihezi", - "Fengshan", - "Lobito", - "Tsuyama", - "Hidalgo", - "Netanya", - "Roseau", - "Chaoyang", - "Jersey City", - "Nîmes", - "Tungi", - "Kallithea", - "Saga", - "Buon Ma Thuot", - "Guarenas", - "Antipolo", - "Toronto", - "Offenbach am Main", - "Dayr al-Zawr", - "Daxian", - "Jena", - "Itaboraí", - "Ikorodu", - "Dongwan", - "Sagay", - "Dublin", - "Ejigbo", - "Tver", - "Bettiah", - "al-Nasiriya", - "Ma´anshan", - "Randburg", - "Jaén", - "Dinajpur", - "Shubra al-Khayma", - "Ambala Sadar", - "Mississauga", - "Kyongju", - "Richmond Hill", - "Foshan", - "Dakar", - "Changchun", - "Cubatão", - "Uiwang", - "Cadiz", - "Novouralsk", - "Jessore", - "Thiès", - "Cape Breton", - "Anand", - "Olongapo", - "Tai´an", - "Piura", - "Krasnyi Lutš", - "Kueishan", - "Alberton", - "Effon-Alaiye", - "Siegen", - "Oyama", - "Freiburg im Breisgau", - "Bikaner", - "Ahmadnagar", - "Tiefa", - "Lauro de Freitas", - "Yuanlin", - "Gaya", - "Topeka", - "Herakleion", - "Novara", - "Oakville", - "Saltillo", - "Swansea", - "Firozabad", - "Jambi", - "Dushanbe", - "Chimoio", - "Baquba", - "Salto", - "The Valley", - "Fort Worth", - "Nogales", - "General Escobedo", - "Chuzhou", - "Okazaki", - "Ife", - "Río Cuarto", - "Urawa", - "Castilla", - "Fuzhou", - "Mobile", - "Dipolog", - "Makijivka", - "Altamira", - "Tianshui", - "Fontana", - "Cam Pha", - "Belmopan", - "Yaoundé", - "Lagos de Moreno", - "Metepec", - "Olinda", - "Naltšik", - "Jilin", - "Crawley", - "Ansan", - "Takarazuka", - "Conakry", - "Praia Grande", - "Matanzas", - "Kisarazu", - "Arden-Arcade", - "Dongtai", - "San Francisco", - "Iguala de la Independencia", - "Geneve", - "Sawhaj", - "Kairouan", - "Jos", - "Burnaby", - "José Azueta", - "Abilene", - "Delhi", - "Yamoussoukro", - "Luziânia", - "La Romana", - "al-Kharj", - "Livonia", - "Bello", - "al-Raqqa", - "Ternopil", - "Belford Roxo", - "Mokpo", - "Bergisch Gladbach", - "Dumaguete", - "Sokoto", - "Funabashi", - "Vishakhapatnam", - "Shomolu", - "Handa", - "Habarovsk", - "Chelmsford", - "Dhaka", - "Chandannagar", - "Chalco", - "Lilongwe", - "Fuchu", - "Tarragona", - "Tavoy (Dawei)", - "Uberlândia", - "Molodetšno", - "Argenteuil", - "Nanyang", - "Downey", - "Providence", - "Hofu", - "Besançon", - "Torbat-e Heydariyeh", - "Ixtlahuaca", - "San Fernando de Apure", - "Tlajomulco de Zúñiga", - "Zhengzhou", - "Akron", - "Kaluga", - "Sambalpur", - "Kamalia", - "Matadi", - "Rio Grande", - "Zanjan", - "Pekan Baru", - "Opole", - "Guasave", - "Hirakata", - "Limassol", - "Kamarhati", - "Vanderbijlpark", - "Tottori", - "Hayward", - "Tarsus", - "Pereira", - "al-Amara", - "Breda", - "Giron", - "Mahajanga", - "Vejalpur", - "Minatitlán", - "Worthing", - "Zaanstad", - "Basra", - "Lashio (Lasho)", - "Ube", - "Heze", - "Rehovot", - "Sirsa", - "Aizawl", - "Gondiya", - "Konan", - "Tellicherry (Thalassery)", - "Gibraltar", - "Sevastopol", - "Dewas", - "Valle de Santiago", - "Nova Friburgo", - "Korolev", - "Kaiserslautern", - "Antwerpen", - "Nahodka", - "Medina", - "Almería", - "Saidpur", - "Doha", - "Bragança Paulista", - "Namangan", - "Plovdiv", - "Botshabelo", - "Zunyi", - "Barreiras", - "Ribeirão das Neves", - "Manisa", - "Montes Claros", - "al-Ramadi", - "Sariwon", - "Norwich", - "Ourense (Orense)", - "Wah", - "Prokopjevsk", - "Arica", - "Ilam", - "Puri", - "Denver", - "Novotroitsk", - "Taliao", - "Sliven", - "Termiz", - "Mandaue", - "Kuantan", - "Kütahya", - "San Nicolás de los Arroyos", - "Crato", - "Urmia", - "Carolina", - "Austin", - "Santiago", - "Sumqayit", - "Ijebu-Ode", - "Lausanne", - "Tongchuan", - "Umeå", - "Chengdu", - "al-Diwaniya", - "Hospet", - "Fort Collins", - "Meknès", - "Bijapur", - "Utrecht", - "Nobeoka", - "Ramat Gan", - "Mendoza", - "Mission Viejo", - "Meixian", - "Blida (el-Boulaida)", - "Colima", - "Shaowu", - "Balašiha", - "Saveh", - "Nakhon Sawan", - "Shahjahanpur", - "Joliet", - "Kokubunji", - "Xianning", - "Wien", - "Petare", - "Warri", - "Petah Tiqwa", - "El Alto", - "Fayetteville", - "Orlando", - "Ufa", - "Portmore", - "Roubaix", - "Kraków", - "Dunhua", - "Pasig", - "Çorum", - "Bandirma", - "Almaty", - "Maunath Bhanjan", - "Campos dos Goytacazes", - "Camagüey", - "Fukushima", - "Itapetininga", - "Chong-up", - "Noda", - "Settat", - "Longkou", - "Datong", - "Lubbock", - "Santa Clarita", - "Hassan", - "General Mariano Alvarez", - "San Pedro de Macorís", - "Ligao", - "Komatsu", - "Maseru", - "Kuznetsk", - "Haldia", - "Kaifeng", - "Titagarh", - "Digos", - "Esfahan", - "Cuernavaca", - "Šumen", - "Ichihara", - "Atizapán de Zaragoza", - "Surendranagar", - "Foggia", - "Tulcea", - "Salt Lake City", - "Nouakchott", - "Santiago de Chile", - "Qinhuangdao", - "Qarchak", - "San Luis Potosí", - "Zhezqazghan", - "Patos de Minas", - "Faridabad", - "Alicante [Alacant]", - "Olsztyn", - "Beira", - "Pohang", - "Aberdeen", - "Higashikurume", - "Lhasa", - "Sapporo", - "Udaipur", - "Ocumare del Tuy", - "Cametá", - "Floridablanca", - "Huaihua", - "Ocosingo", - "Campo Grande", - "Palmdale", - "Blitar", - "Toyonaka", - "Tiruchirapalli", - "Gdynia", - "Navadwip", - "Niigata", - "Huelva", - "Aqtöbe", - "Espoo", - "Jevpatorija", - "South Bend", - "Monclova", - "New Orleans", - "Karachi", - "Ebetsu", - "Giza", - "Milagro", - "Maidstone", - "Suceava", - "Torreón", - "Sinuiju", - "Zabol", - "Ajman", - "Texcoco", - "Kükon", - "Marawi", - "Suining", - "Fujimi", - "Tjumen", - "Ruse", - "Cabo de Santo Agostinho", - "Minna", - "Brisbane", - "Valdivia", - "Limoges", - "Panjin", - "Kasukabe", - "Zahedan", - "Ilagan", - "Taubaté", - "Grozny", - "Parbhani", - "Syracuse", - "Kusatsu", - "Perth", - "Paulista", - "Taman", - "Bern", - "Milwaukee", - "Pingyi", - "Garut", - "Gorlivka", - "Korba", - "Pak Kret", - "Ravenna", - "El Araich", - "Mirzapur-cum-Vindhyachal", - "Melipilla", - "Pasto", - "Ashqelon", - "Ogbomosho", - "Masjed-e-Soleyman", - "Volzski", - "Kamyšin", - "Otaru", - "Jiamusi", - "Gebze", - "Palayankottai", - "Chaohu", - "Tébessa", - "Green Bay", - "Singapore", - "al-Zarqa", - "Talisay", - "Hailar", - "Lugansk", - "Puno", - "Jakutsk", - "Liupanshui", - "Jundíaí", - "Lungtan", - "Francistown", - "Huntington Beach", - "Lucknow", - "Sekondi-Takoradi", - "West Valley City", - "Kafr al-Shaykh", - "Bishkek", - "Hamburg", - "Yakeshi", - "Shaoguan", - "Novotšeboksarsk", - "Port Moresby", - "Syrakusa", - "Penza", - "Longueuil", - "Chinju", - "General Santos", - "El-Aaiún", - "Maoming", - "Poznan", - "Amritsar", - "Carrefour", - "Noginsk", - "Bærum", - "Alagoinhas", - "Ichon", - "Temuco", - "Sapele", - "Hami", - "Takasago", - "Pisa", - "Rotherham", - "Kostjantynivka", - "Jhelum", - "Assuan", - "Juárez", - "Lódz", - "Mbour" - ], - "grid": { - "enabled": true - }, - "labels": { - "enabled": true - }, - "ticks": {}, - "title": {}, - "type": "category" - } -} diff --git a/src/plugins/d3/__stories__/scatter/BigLegend.stories.tsx b/src/plugins/d3/__stories__/scatter/BigLegend.stories.tsx deleted file mode 100644 index 80b91711..00000000 --- a/src/plugins/d3/__stories__/scatter/BigLegend.stories.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {boolean, number, select} from '@storybook/addon-knobs'; -import {Meta, Story} from '@storybook/react'; -import random from 'lodash/random'; -import range from 'lodash/range'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef} from '../../../../types'; -import type {ChartKitWidgetData, ScatterSeries} from '../../../../types/widget-data'; -import {randomString} from '../../../../utils'; - -const TEMPLATE_STRING = '0123456789abcdefghijklmnopqrstuvwxyz'; - -const generateSeriesData = (seriesCount = 5): ScatterSeries[] => { - return range(0, seriesCount).map(() => { - return { - type: 'scatter', - data: [ - { - x: random(0, 1000), - y: random(0, 1000), - }, - ], - name: `${randomString(random(3, 15), TEMPLATE_STRING)}`, - }; - }); -}; - -const shapeData = (): ChartKitWidgetData => { - return { - legend: { - align: select('Align', ['left', 'right', 'center'], 'left', 'legend'), - margin: number('Margin', 15, undefined, 'legend'), - itemDistance: number('Item distance', 20, undefined, 'legend'), - }, - series: { - data: generateSeriesData(number('Amount of series', 1000, undefined, 'legend')), - }, - xAxis: { - labels: { - enabled: boolean('Show labels', true, 'xAxis'), - }, - }, - yAxis: [ - { - labels: { - enabled: boolean('Show labels', true, 'yAxis'), - }, - }, - ], - }; -}; - -const Template: Story = () => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - const data = shapeData(); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BigLegend = Template.bind({}); - -const meta: Meta = { - title: 'Plugins/D3/Scatter', -}; - -export default meta; diff --git a/src/plugins/d3/__stories__/scatter/LinearCategories.stories.tsx b/src/plugins/d3/__stories__/scatter/LinearCategories.stories.tsx deleted file mode 100644 index 7c1b559e..00000000 --- a/src/plugins/d3/__stories__/scatter/LinearCategories.stories.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {radios, select, text, withKnobs} from '@storybook/addon-knobs'; -import {Meta, Story} from '@storybook/react'; -import random from 'lodash/random'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef} from '../../../../types'; -import type { - ChartKitWidgetAxis, - ChartKitWidgetData, - ScatterSeries, - ScatterSeriesData, -} from '../../../../types/widget-data'; - -import penguins from '../penguins.json'; - -const shapeScatterSeriesData = (args: {data: Record[]; groupBy: string; map: any}) => { - const {data, groupBy, map} = args; - - return data.reduce>((acc, d) => { - const seriesName = d[groupBy] as string; - - if (!seriesName) { - return acc; - } - - if (!acc[seriesName]) { - acc[seriesName] = []; - } - - const categoriesType = map.categoriesType as 'x' | 'y' | 'none' | undefined; - const isCategorical = categoriesType === 'x' || categoriesType === 'y'; - - if (isCategorical && map.category) { - acc[seriesName].push({ - x: d[map.x], - y: d[map.y], - radius: random(3, 6), - [map.categoriesType]: d[map.category], - }); - } else if (!isCategorical) { - acc[seriesName].push({ - x: d[map.x], - y: d[map.y], - radius: random(3, 6), - }); - } - - return acc; - }, {}); -}; - -const shapeScatterSeries = (data: Record) => { - return Object.keys(data).reduce((acc, name) => { - acc.push({ - type: 'scatter', - data: data[name], - name, - }); - - return acc; - }, []); -}; - -const shapeScatterChartData = ( - series: ScatterSeries[], - categoriesType: 'none' | 'x' | 'y', - categories?: string[], -): ChartKitWidgetData => { - let xAxis: ChartKitWidgetAxis = { - title: { - text: text('X axis title', ''), - }, - }; - - let yAxis: ChartKitWidgetAxis = { - title: { - text: text('Y axis title', ''), - }, - }; - - if (categories && categoriesType === 'x') { - xAxis = { - ...xAxis, - type: 'category', - categories, - }; - } - - if (categories && categoriesType === 'y') { - yAxis = { - ...yAxis, - type: 'category', - categories, - }; - } - - return { - series: { - data: series, - }, - xAxis, - yAxis: [yAxis], - title: { - text: text('title', 'Chart title'), - }, - }; -}; - -const Template: Story = () => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - const x = select( - 'x', - ['culmen_length_mm', 'culmen_depth_mm', 'flipper_length_mm', 'body_mass_g'], - 'culmen_length_mm', - ); - const y = select( - 'y', - ['culmen_length_mm', 'culmen_depth_mm', 'flipper_length_mm', 'body_mass_g'], - 'culmen_depth_mm', - ); - - const groupBy = select('groupBy', ['species', 'island', 'sex'], 'species'); - const categoriesType = radios('categoriesType', {none: 'none', x: 'x', y: 'y'}, 'none'); - const category = - categoriesType === 'none' - ? undefined - : select('category', ['species', 'island', 'sex'], 'island'); - let categories: string[] | undefined; - - if (categoriesType !== 'none' && category) { - categories = penguins.reduce((acc, p) => { - const cerrentCategory = p[category]; - - if (typeof cerrentCategory === 'string' && !acc.includes(cerrentCategory)) { - acc.push(cerrentCategory); - } - - return acc; - }, []); - } - const shapedScatterSeriesData = shapeScatterSeriesData({ - data: penguins, - groupBy, - map: {x, y, category, categoriesType}, - }); - const shapedScatterSeries = shapeScatterSeries(shapedScatterSeriesData); - const data = shapeScatterChartData(shapedScatterSeries, categoriesType, categories); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const LinearAndCategories = Template.bind({}); - -const meta: Meta = { - title: 'Plugins/D3/Scatter', - decorators: [withKnobs], -}; - -export default meta; diff --git a/src/plugins/d3/__stories__/scatter/PerformanceIssue.stories.tsx b/src/plugins/d3/__stories__/scatter/PerformanceIssue.stories.tsx deleted file mode 100644 index 2174fd4f..00000000 --- a/src/plugins/d3/__stories__/scatter/PerformanceIssue.stories.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; -import {randomNormal} from 'd3'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData} from '../../../../types'; -import {randomString} from '../../../../utils'; - -const randomFn = randomNormal(0, 10); -const randomStr = () => randomString(Math.random() * 10, 'absdEFGHIJklmnopqrsTUvWxyz'); - -const ChartStory = (args: {categoriesCount: number; seriesCount: number}) => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - - const widgetData: ChartKitWidgetData = React.useMemo(() => { - const categories = Array.from({length: args.categoriesCount}).map(randomStr); - const series = Array.from({length: args.seriesCount}).map(randomStr); - - return { - xAxis: { - type: 'category', - categories: categories, - }, - series: { - data: series.map((s) => ({ - type: 'scatter', - name: s, - data: categories.map((_, i) => ({ - x: i, - y: randomFn(), - })), - })), - }, - }; - }, [args]); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PerformanceIssueScatter: StoryObj = { - name: 'Performance issue', - args: { - categoriesCount: 5000, - seriesCount: 2, - }, - argTypes: { - categoriesCount: { - control: 'number', - }, - }, -}; - -export default { - title: 'Plugins/D3/Scatter', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/scatter/Playground.stories.tsx b/src/plugins/d3/__stories__/scatter/Playground.stories.tsx deleted file mode 100644 index eb920b95..00000000 --- a/src/plugins/d3/__stories__/scatter/Playground.stories.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; -import nintendoGames from '../../examples/nintendoGames'; - -function prepareData() { - const dataset = nintendoGames.filter((d) => d.date && d.user_score); - const data = dataset.map((d) => ({ - x: d.date || undefined, - y: d.user_score || undefined, - custom: d, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'scatter', - data, - name: 'Scatter series', - }, - ], - }, - yAxis: [ - { - title: { - text: 'User score', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Release dates', - }, - }, - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; - - return widgetData; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PlaygroundBarYChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Scatter', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/scatter/Scatter.stories.tsx b/src/plugins/d3/__stories__/scatter/Scatter.stories.tsx deleted file mode 100644 index 921cd74c..00000000 --- a/src/plugins/d3/__stories__/scatter/Scatter.stories.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {withKnobs} from '@storybook/addon-knobs'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {settings} from '../../../../libs'; -import {Basic} from '../../examples/scatter/Basic'; - -const ChartStory = ({Chart}: {Chart: React.FC}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const BasicScatterStory: StoryObj = { - name: 'Basic', - args: { - Chart: Basic, - }, -}; - -export default { - title: 'Plugins/D3/Scatter', - decorators: [withKnobs], - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/scatter/Timestamp.stories.tsx b/src/plugins/d3/__stories__/scatter/Timestamp.stories.tsx deleted file mode 100644 index 02523782..00000000 --- a/src/plugins/d3/__stories__/scatter/Timestamp.stories.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; -import {Button} from '@gravity-ui/uikit'; -import {date} from '@storybook/addon-knobs'; -import {Meta, Story} from '@storybook/react'; -import {range} from 'd3'; -import random from 'lodash/random'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef} from '../../../../types'; -import type { - ChartKitWidgetData, - ScatterSeries, - ScatterSeriesData, -} from '../../../../types/widget-data'; - -const rowData: ScatterSeriesData[] = [ - { - y: 86.71905594602345, - custom: 'green', - }, - { - y: 86.73089353359981, - custom: 'yellow', - }, - { - y: 86.53675705168267, - custom: 'red', - }, - { - y: 86.47880981408552, - custom: 'blue', - }, - { - y: 86.4108836764148, - custom: 'gray', - }, - { - y: 86.73440096266042, - custom: 'pink', - }, - { - y: 86.64935929597681, - custom: 'purple', - }, -]; - -const shapeData = (data: Record[]): ChartKitWidgetData => { - const startDate = date('startDate', new Date(2023, 6, 28, 6)).valueOf(); - const endDate = date('endDate', new Date(2023, 6, 30, 6)).valueOf(); - const step = (endDate - startDate) / data.length; - const dates = range(rowData.length).map((d) => startDate + step * d); - - const scatterData: ScatterSeriesData[] = data.map((d, i) => ({ - x: dates[i], - y: d.y, - radius: random(3, 6), - custom: d.custom, - })); - - const scatterSeries: ScatterSeries = { - type: 'scatter', - data: scatterData, - name: 'some-name', - }; - - return { - series: { - data: [scatterSeries], - }, - xAxis: { - type: 'datetime', - }, - yAxis: [ - { - lineColor: 'transparent', - }, - ], - tooltip: { - renderer: ({hovered}) => { - const d = hovered[0].data as ScatterSeriesData; - return
{dateTime({input: d.x}).format('LL')}
; - }, - }, - }; -}; - -const Template: Story = () => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - const data = shapeData(rowData); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const Timestamp = Template.bind({}); - -const meta: Meta = { - title: 'Plugins/D3/Scatter', -}; - -export default meta; diff --git a/src/plugins/d3/__stories__/treemap/HtmlLabels.stories.tsx b/src/plugins/d3/__stories__/treemap/HtmlLabels.stories.tsx deleted file mode 100644 index 1a5788f7..00000000 --- a/src/plugins/d3/__stories__/treemap/HtmlLabels.stories.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row} from '@gravity-ui/uikit'; -import type {StoryObj} from '@storybook/react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {Loader} from '../../../../components/Loader/Loader'; -import {settings} from '../../../../libs'; -import type {ChartKitWidgetData} from '../../../../types'; -import {TreemapSeries} from '../../../../types'; -import {ExampleWrapper} from '../../examples/ExampleWrapper'; -import {D3Plugin} from '../../index'; - -const TreemapWithHtmlLabels = () => { - const [loading, setLoading] = React.useState(true); - - React.useEffect(() => { - settings.set({plugins: [D3Plugin]}); - setLoading(false); - }, []); - - if (loading) { - return ; - } - - const styledLabel = (label: string) => - `${label}`; - const treemapSeries: TreemapSeries = { - type: 'treemap', - name: 'Example', - dataLabels: { - enabled: true, - html: true, - align: 'right', - }, - layoutAlgorithm: 'binary', - levels: [ - {index: 1, padding: 3}, - {index: 2, padding: 1}, - ], - data: [ - {name: styledLabel('One'), value: 15}, - {name: styledLabel('Two'), id: 'Two'}, - {name: [styledLabel('Two'), '1'], value: 2, parentId: 'Two'}, - {name: [styledLabel('Two'), '2'], value: 8, parentId: 'Two'}, - ], - }; - - const getWidgetData = (): ChartKitWidgetData => ({ - series: { - data: [treemapSeries], - }, - }); - - return ( - - - - - - - - - - ); -}; - -export const TreemapWithHtmlLabelsStory: StoryObj = { - name: 'Html in labels', -}; - -export default { - title: 'Plugins/D3/Treemap', - component: TreemapWithHtmlLabels, -}; diff --git a/src/plugins/d3/__stories__/treemap/Playground.stories.tsx b/src/plugins/d3/__stories__/treemap/Playground.stories.tsx deleted file mode 100644 index c7b145ce..00000000 --- a/src/plugins/d3/__stories__/treemap/Playground.stories.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import type {ChartKitRef, ChartKitWidgetData, TreemapSeries} from '../../../../types'; - -const prepareData = (): ChartKitWidgetData => { - const treemapSeries: TreemapSeries = { - type: 'treemap', - name: 'Example', - dataLabels: { - enabled: true, - }, - layoutAlgorithm: 'binary', - levels: [ - {index: 1, padding: 5}, - {index: 2, padding: 3}, - {index: 3, padding: 1}, - ], - data: [ - {name: 'One', value: 15}, - {name: 'Two', value: 10}, - {name: 'Three', value: 15}, - {name: 'Four'}, - {name: ['Four', '1'], value: 5, parentId: 'Four'}, - {name: 'Four-2', parentId: 'Four'}, - {name: 'Four-3', value: 4, parentId: 'Four'}, - {name: 'Four-2-1', value: 5, parentId: 'Four-2'}, - {name: 'Four-2-2', value: 7, parentId: 'Four-2'}, - {name: 'Four-2-3', value: 10, parentId: 'Four-2'}, - ], - }; - - return { - series: { - data: [treemapSeries], - }, - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; -}; - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - const chartkitRef = React.useRef(); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const TreemapPlayground: StoryObj = { - name: 'Playground', - args: {data: prepareData()}, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Treemap', - component: ChartStory, -}; diff --git a/src/plugins/d3/__stories__/waterfall/Playground.stories.tsx b/src/plugins/d3/__stories__/waterfall/Playground.stories.tsx deleted file mode 100644 index 354f8dce..00000000 --- a/src/plugins/d3/__stories__/waterfall/Playground.stories.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; - -import {Button} from '@gravity-ui/uikit'; -import {action} from '@storybook/addon-actions'; -import {StoryObj} from '@storybook/react'; - -import {D3Plugin} from '../..'; -import {ChartKit} from '../../../../components/ChartKit'; -import {settings} from '../../../../libs'; -import {ChartKitWidgetData} from '../../../../types'; - -function prepareData() { - const result: ChartKitWidgetData = { - series: { - data: [ - { - type: 'waterfall', - data: [ - {y: 100, x: 0}, - {y: -20, x: 1}, - {y: -15, x: 2}, - {y: 30, x: 3}, - {y: 45, x: 4}, - {y: 10, x: 5}, - {y: -120, x: 6}, - {y: 30, x: 7}, - {y: 10, x: 8}, - {y: -20, x: 9}, - {y: -5, x: 10}, - {y: 35, x: 11}, - {total: true, x: 12}, - ], - name: 'Profit', - dataLabels: {enabled: true}, - }, - ], - }, - xAxis: { - type: 'category', - categories: [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'Jun', - 'Jul', - 'Aug', - 'Sep', - 'Oct', - 'Nov', - 'Dec', - 'Totals', - ], - labels: { - enabled: true, - rotation: 30, - }, - }, - yAxis: [ - { - labels: { - enabled: true, - rotation: -90, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - chart: { - events: { - click: action('chart.events.click'), - }, - }, - }; - - return result; -} - -const ChartStory = ({data}: {data: ChartKitWidgetData}) => { - const [shown, setShown] = React.useState(false); - - if (!shown) { - settings.set({plugins: [D3Plugin]}); - return ; - } - - return ( -
- -
- ); -}; - -export const PlaygroundWaterfallChartStory: StoryObj = { - name: 'Playground', - args: { - data: prepareData(), - }, - argTypes: { - data: { - control: 'object', - }, - }, -}; - -export default { - title: 'Plugins/D3/Waterfall', - component: ChartStory, -}; diff --git a/src/plugins/d3/examples/ExampleWrapper.tsx b/src/plugins/d3/examples/ExampleWrapper.tsx deleted file mode 100644 index a46fba74..00000000 --- a/src/plugins/d3/examples/ExampleWrapper.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; - -type Props = { - children?: React.ReactNode; - styles?: React.CSSProperties; -}; - -export const ExampleWrapper = (props: Props) => { - const styles: React.CSSProperties = { - height: 280, - ...props.styles, - }; - return
{props.children}
; -}; diff --git a/src/plugins/d3/examples/area/Basic.tsx b/src/plugins/d3/examples/area/Basic.tsx deleted file mode 100644 index b88f16b8..00000000 --- a/src/plugins/d3/examples/area/Basic.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {AreaSeries, AreaSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData(): AreaSeries[] { - const games = nintendoGames.filter((d) => { - return d.date && d.user_score && d.genres.includes('Puzzle'); - }); - - return [ - { - name: 'User score', - type: 'area', - data: games.map((d) => { - return { - x: Number(d.date), - y: Number(d.user_score), - }; - }), - }, - ]; -} - -export const Basic = () => { - const series = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series, - }, - xAxis: { - type: 'datetime', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/area/NegativeValues.tsx b/src/plugins/d3/examples/area/NegativeValues.tsx deleted file mode 100644 index 32284ad3..00000000 --- a/src/plugins/d3/examples/area/NegativeValues.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; - -export const NegativeValues = () => { - const data = [ - {x: 0, y: 10}, - {x: 1, y: 20}, - {x: 2, y: -30}, - {x: 3, y: 100}, - ]; - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'area', - data: data, - name: 'Min temperature', - }, - ], - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/area/PercentStacking.tsx b/src/plugins/d3/examples/area/PercentStacking.tsx deleted file mode 100644 index c1f92a6b..00000000 --- a/src/plugins/d3/examples/area/PercentStacking.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {AreaSeries, AreaSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -const years = Array.from( - new Set( - nintendoGames.map((d) => - d.date ? String(new Date(d.date as number).getFullYear()) : 'unknown', - ), - ), -).sort(); - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? String(new Date(d.date as number).getFullYear()) : 'unknown'), - ); - const series = grouped.map(([platform, gamesByYear]) => { - const platformGames = Object.fromEntries(gamesByYear) || {}; - return { - name: platform, - data: years.reduce((acc, year) => { - if (year in platformGames) { - acc.push({ - x: year, - y: platformGames[year].length, - }); - } - - return acc; - }, []), - }; - }); - - return {series}; -} - -export const PercentStackingArea = () => { - const {series} = prepareData(); - - const data = series.map((s) => { - return { - type: 'area', - stacking: 'percent', - name: s.name, - data: s.data, - } as AreaSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - xAxis: { - type: 'category', - categories: years, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/area/StackedArea.tsx b/src/plugins/d3/examples/area/StackedArea.tsx deleted file mode 100644 index 09e13984..00000000 --- a/src/plugins/d3/examples/area/StackedArea.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {AreaSeries, AreaSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -const years = Array.from( - new Set( - nintendoGames.map((d) => - d.date ? String(new Date(d.date as number).getFullYear()) : 'unknown', - ), - ), -).sort(); - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? String(new Date(d.date as number).getFullYear()) : 'unknown'), - ); - const series = grouped.map(([platform, gamesByYear]) => { - const platformGames = Object.fromEntries(gamesByYear) || {}; - return { - name: platform, - data: years.reduce((acc, year) => { - if (year in platformGames) { - acc.push({ - x: year, - y: platformGames[year].length, - }); - } - - return acc; - }, []), - }; - }); - - return {series}; -} - -export const StackedArea = () => { - const {series} = prepareData(); - - const data = series.map((s) => { - return { - type: 'area', - stacking: 'normal', - name: s.name, - data: s.data, - } as AreaSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - xAxis: { - type: 'category', - categories: years, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/area/TwoYAxis.tsx b/src/plugins/d3/examples/area/TwoYAxis.tsx deleted file mode 100644 index e96dcfd4..00000000 --- a/src/plugins/d3/examples/area/TwoYAxis.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const TwoYAxis = () => { - const data = marsWeatherData as any[]; - const pressureData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.pressure, - })); - - const tempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.max_temp - d.min_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'area', - data: pressureData, - name: 'Pressure', - yAxis: 0, - }, - { - type: 'area', - data: tempData, - name: 'Temperature range', - yAxis: 1, - }, - ], - }, - yAxis: [ - { - title: { - text: 'Pressure', - }, - }, - { - title: { - text: 'Temperature range', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - ticks: {pixelInterval: 200}, - }, - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/Basic.tsx b/src/plugins/d3/examples/bar-x/Basic.tsx deleted file mode 100644 index 57b1a82b..00000000 --- a/src/plugins/d3/examples/bar-x/Basic.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarXSeries, BarXSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData( - {field, filterNulls}: {field: 'platform' | 'meta_score' | 'date'; filterNulls?: boolean} = { - field: 'platform', - }, -) { - const gamesByPlatform = groups(nintendoGames, (item) => item[field]); - let resultData = gamesByPlatform; - - if (filterNulls) { - resultData = gamesByPlatform.filter(([value]) => typeof value === 'number'); - } - - const data = resultData.map(([value, games]) => ({ - x: value, - y: games.length, - })); - - return { - categories: resultData.map(([key]) => key), - series: [ - { - data, - name: 'Games released', - }, - ], - }; -} - -export const BasicBarXChart = () => { - const {categories, series} = prepareData(); - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'bar-x', - data: s.data as BarXSeriesData[], - name: s.name, - })), - }, - xAxis: { - type: 'category', - categories: categories.map(String), - title: { - text: 'Game Platforms', - }, - }, - yAxis: [{title: {text: 'Number of games released'}}], - }; - - return ( - - - - ); -}; - -export const BasicLinearBarXChart = () => { - const {series} = prepareData({field: 'meta_score'}); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'bar-x', - data: s.data as BarXSeriesData[], - name: s.name, - })), - }, - xAxis: { - title: { - text: 'Meta scores', - }, - }, - }; - - return ( - - - - ); -}; - -export const BasicDateTimeBarXChart = () => { - const {series} = prepareData({field: 'date', filterNulls: true}); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'bar-x', - data: s.data as BarXSeriesData[], - name: s.name, - })), - }, - xAxis: { - type: 'datetime', - title: { - text: 'Release date', - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/DataLabels.tsx b/src/plugins/d3/examples/bar-x/DataLabels.tsx deleted file mode 100644 index cbc42294..00000000 --- a/src/plugins/d3/examples/bar-x/DataLabels.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; - -import {groups, sort} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarXSeries, BarXSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -const years = Array.from( - new Set( - nintendoGames.map((g) => - g.date ? new Date(g.date as number).getFullYear().toString() : 'unknown', - ), - ), -); - -function prepareData(): BarXSeries[] { - const games = sort( - nintendoGames.filter((d) => { - return d.date && d.user_score; - }), - (d) => d.date, - ); - - const groupByYear = (d: any) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'); - - const byGenre = (genre: string): BarXSeries => { - const data = groups( - games.filter((d) => d.genres.includes(genre)), - groupByYear, - ).map(([year, items]) => { - return { - x: years.indexOf(String(year)), - y: items.length, - }; - }); - - return { - type: 'bar-x', - name: genre, - dataLabels: { - enabled: true, - }, - stacking: 'normal', - data, - }; - }; - - return [byGenre('Strategy'), byGenre('Shooter'), byGenre('Puzzle'), byGenre('Action')]; -} - -export const DataLabels = () => { - const series = prepareData(); - const widgetData: ChartKitWidgetData = { - series: { - data: series, - }, - xAxis: { - categories: years, - type: 'category', - title: { - text: 'Release year', - }, - ticks: {pixelInterval: 200}, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/GroupedColumns.tsx b/src/plugins/d3/examples/bar-x/GroupedColumns.tsx deleted file mode 100644 index 1e808829..00000000 --- a/src/plugins/d3/examples/bar-x/GroupedColumns.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarXSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const displayedYears = [2015, 2016, 2017, 2018, 2019]; - const games = nintendoGames.filter((ng) => - displayedYears.includes(new Date(ng.date as number).getFullYear()), - ); - const grouped = groups( - games, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - x: String(year), - y: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const GroupedColumns = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-x', - name: s.name, - data: s.data, - } as BarXSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data, - }, - xAxis: { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/NegativeValues.tsx b/src/plugins/d3/examples/bar-x/NegativeValues.tsx deleted file mode 100644 index 5074b07c..00000000 --- a/src/plugins/d3/examples/bar-x/NegativeValues.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const NegativeValues = () => { - const data = marsWeatherData.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.min_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-x', - data: data, - name: 'Min temperature', - }, - ], - }, - yAxis: [ - { - title: { - text: 'Min temperature', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - ticks: {pixelInterval: 200}, - }, - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/PercentStack.tsx b/src/plugins/d3/examples/bar-x/PercentStack.tsx deleted file mode 100644 index b07aef0a..00000000 --- a/src/plugins/d3/examples/bar-x/PercentStack.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarXSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - x: String(year), - y: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const PercentStackColumns = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-x', - stacking: 'percent', - name: s.name, - data: s.data, - } as BarXSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - xAxis: { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/StackedColumns.tsx b/src/plugins/d3/examples/bar-x/StackedColumns.tsx deleted file mode 100644 index 40993897..00000000 --- a/src/plugins/d3/examples/bar-x/StackedColumns.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarXSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - x: String(year), - y: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const StackedColumns = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-x', - stacking: 'normal', - name: s.name, - data: s.data, - } as BarXSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - xAxis: { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-x/TwoYAxis.tsx b/src/plugins/d3/examples/bar-x/TwoYAxis.tsx deleted file mode 100644 index ab6d9e64..00000000 --- a/src/plugins/d3/examples/bar-x/TwoYAxis.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const TwoYAxis = () => { - const data = marsWeatherData as any[]; - const pressureData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.pressure, - })); - - const tempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.max_temp - d.min_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-x', - data: pressureData, - name: 'Pressure', - yAxis: 0, - }, - { - type: 'bar-x', - data: tempData, - name: 'Temperature range', - yAxis: 1, - }, - ], - }, - yAxis: [ - { - title: { - text: 'Pressure', - }, - }, - { - title: { - text: 'Temperature range', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - ticks: {pixelInterval: 200}, - }, - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-y/Basic.tsx b/src/plugins/d3/examples/bar-y/Basic.tsx deleted file mode 100644 index 5e466f85..00000000 --- a/src/plugins/d3/examples/bar-y/Basic.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarYSeries, BarYSeriesData, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData(field: 'platform' | 'meta_score' | 'date' = 'platform') { - const gamesByPlatform = groups(nintendoGames, (item) => item[field]); - const data = gamesByPlatform.map(([value, games]) => ({ - y: value, - x: games.length, - })); - - return { - categories: gamesByPlatform.map(([key]) => key), - series: [ - { - data, - name: 'Games released', - }, - ], - }; -} - -export const Basic = () => { - const {categories, series} = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'bar-y', - data: s.data as BarYSeriesData[], - name: s.name, - })), - }, - xAxis: {title: {text: 'Number of games released'}}, - yAxis: [ - { - type: 'category', - categories: categories.map(String), - title: { - text: 'Game Platforms', - }, - }, - ], - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-y/GroupedColumns.tsx b/src/plugins/d3/examples/bar-y/GroupedColumns.tsx deleted file mode 100644 index 88a6eaa8..00000000 --- a/src/plugins/d3/examples/bar-y/GroupedColumns.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarYSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const displayedYears = [2015, 2016, 2017, 2018, 2019]; - const games = nintendoGames.filter((ng) => - displayedYears.includes(new Date(ng.date as number).getFullYear()), - ); - const grouped = groups( - games, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - y: String(year), - x: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const GroupedColumns = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-y', - name: s.name, - data: s.data, - } as BarYSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - yAxis: [ - { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - ], - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-y/NegativeValues.tsx b/src/plugins/d3/examples/bar-y/NegativeValues.tsx deleted file mode 100644 index c09e54dc..00000000 --- a/src/plugins/d3/examples/bar-y/NegativeValues.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const NegativeValues = () => { - const data = marsWeatherData.map((d) => ({ - y: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - x: d.min_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'bar-y', - data: data, - name: 'Min temperature', - }, - ], - }, - xAxis: { - title: { - text: 'Min temperature', - }, - }, - yAxis: [ - { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - }, - ], - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-y/PercentStacking.tsx b/src/plugins/d3/examples/bar-y/PercentStacking.tsx deleted file mode 100644 index b7568758..00000000 --- a/src/plugins/d3/examples/bar-y/PercentStacking.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarYSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - y: String(year), - x: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const PercentStackingBars = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-y', - stacking: 'percent', - name: s.name, - data: s.data, - } as BarYSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - yAxis: [ - { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - ], - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/bar-y/StackedColumns.tsx b/src/plugins/d3/examples/bar-y/StackedColumns.tsx deleted file mode 100644 index e22ce755..00000000 --- a/src/plugins/d3/examples/bar-y/StackedColumns.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {BarYSeries, ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const grouped = groups( - nintendoGames, - (d) => d.platform, - (d) => (d.date ? new Date(d.date as number).getFullYear() : 'unknown'), - ); - const categories: string[] = []; - const series = grouped.map(([platform, years]) => { - return { - name: platform, - data: years.map(([year, list]) => { - categories.push(String(year)); - - return { - y: String(year), - x: list.length, - }; - }), - }; - }); - - return {categories, series}; -} - -export const StackedColumns = () => { - const {series, categories} = prepareData(); - const data = series.map((s) => { - return { - type: 'bar-y', - stacking: 'normal', - name: s.name, - data: s.data, - } as BarYSeries; - }); - - const widgetData: ChartKitWidgetData = { - series: { - data: data, - }, - yAxis: [ - { - type: 'category', - categories: categories.sort(), - title: { - text: 'Release year', - }, - }, - ], - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/combined/LineAndBarX.tsx b/src/plugins/d3/examples/combined/LineAndBarX.tsx deleted file mode 100644 index 6370fc31..00000000 --- a/src/plugins/d3/examples/combined/LineAndBarX.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; - -import {groups, max, median, min} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -export const LineAndBarXCombinedChart = () => { - const gamesByPlatform = groups(nintendoGames, (item) => item.platform || 'unknown'); - - const widgetData: ChartKitWidgetData = { - series: { - options: { - line: { - lineWidth: 2, - }, - }, - data: [ - { - type: 'bar-x', - data: gamesByPlatform.map(([value, games]) => ({ - x: value, - y: median(games, (g) => g.user_score || 0), - })), - name: 'Median user score', - }, - { - type: 'line', - data: gamesByPlatform.map(([value, games]) => ({ - x: value, - y: max(games, (g) => g.user_score || 0), - })), - name: 'Max user score', - }, - { - type: 'line', - data: gamesByPlatform.map(([value, games]) => ({ - x: value, - y: min(games, (g) => g.user_score || 10), - })), - name: 'Min user score', - }, - ], - }, - xAxis: { - categories: gamesByPlatform.map(([key]) => key), - type: 'category', - title: { - text: 'Game Platforms', - }, - }, - yAxis: [ - { - title: {text: 'User score'}, - labels: { - enabled: true, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/line/Basic.tsx b/src/plugins/d3/examples/line/Basic.tsx deleted file mode 100644 index 1fbda679..00000000 --- a/src/plugins/d3/examples/line/Basic.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData, LineSeries, LineSeriesData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const dataset = nintendoGames.filter((d) => d.date && d.user_score); - const data = dataset.map((d) => ({ - x: d.date || undefined, - y: d.user_score || undefined, - custom: d, - })); - - return { - series: [ - { - data, - name: 'Nintendo games', - }, - ], - }; -} - -export const Basic = () => { - const {series} = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'line', - data: s.data.filter((d) => d.x), - name: s.name, - })), - }, - yAxis: [ - { - title: { - text: 'User score', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Release dates', - }, - }, - tooltip: { - renderer: (d) => { - const point = d.hovered[0]?.data as LineSeriesData; - - if (!point) { - return null; - } - - const title = point.custom.title; - const score = point.custom.user_score; - const date = dateTime({input: point.custom.date}).format('DD MMM YYYY'); - - return ( - - {title} -
- Release date: {date} -
- User score: {score} -
- ); - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/line/DataLabels.tsx b/src/plugins/d3/examples/line/DataLabels.tsx deleted file mode 100644 index 900ef324..00000000 --- a/src/plugins/d3/examples/line/DataLabels.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData, LineSeries, LineSeriesData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData(): LineSeries[] { - const games = nintendoGames.filter((d) => { - return d.date && d.user_score; - }); - - const byGenre = (genre: string) => { - return games - .filter((d) => d.genres.includes(genre)) - .map((d) => { - return { - x: d.date, - y: d.user_score, - label: `${d.title} (${d.user_score})`, - custom: d, - }; - }) as LineSeriesData[]; - }; - - return [ - { - name: 'Strategy', - type: 'line', - data: byGenre('Strategy'), - dataLabels: { - enabled: true, - }, - }, - { - name: 'Shooter', - type: 'line', - data: byGenre('Shooter'), - dataLabels: { - enabled: true, - }, - }, - ]; -} - -export const DataLabels = () => { - const series = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'line', - data: s.data.filter((d) => d.x), - name: s.name, - dataLabels: { - enabled: true, - }, - })), - }, - yAxis: [ - { - title: { - text: 'User score', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Release dates', - }, - ticks: {pixelInterval: 200}, - }, - tooltip: { - renderer: (d) => { - const point = d.hovered[0]?.data as LineSeriesData; - - if (!point) { - return null; - } - - const title = point.custom.title; - const score = point.custom.user_score; - const date = dateTime({input: point.custom.date}).format('DD MMM YYYY'); - - return ( - - {title} -
- Release date: {date} -
- User score: {score} -
- ); - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/line/LineWithMarkers.tsx b/src/plugins/d3/examples/line/LineWithMarkers.tsx deleted file mode 100644 index a9bc1de4..00000000 --- a/src/plugins/d3/examples/line/LineWithMarkers.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData, LineSeries, LineSeriesData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const dataset = nintendoGames.filter( - (d) => d.date && d.user_score && new Date(d.date) > new Date(2022, 0, 1), - ); - const data = dataset.map((d) => ({ - x: d.date || undefined, - y: d.user_score || undefined, - custom: d, - })); - - return { - series: [ - { - data, - name: 'Nintendo games', - }, - ], - }; -} - -export const LineWithMarkers = () => { - const {series} = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'line', - data: s.data.filter((d) => d.x), - name: s.name, - marker: {enabled: true, symbol: 'square'}, - })), - }, - yAxis: [ - { - title: { - text: 'User score', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Release dates', - }, - }, - tooltip: { - renderer: (d) => { - const point = d.hovered[0]?.data as LineSeriesData; - - if (!point) { - return null; - } - - const title = point.custom.title; - const score = point.custom.user_score; - const date = dateTime({input: point.custom.date}).format('DD MMM YYYY'); - - return ( - - {title} -
- Release date: {date} -
- User score: {score} -
- ); - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/line/LogarithmicAxis.tsx b/src/plugins/d3/examples/line/LogarithmicAxis.tsx deleted file mode 100644 index 93e3303b..00000000 --- a/src/plugins/d3/examples/line/LogarithmicAxis.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; - -import {Col, Container, Row, Text} from '@gravity-ui/uikit'; -import {randomNormal} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; - -export const LineWithLogarithmicAxis = () => { - const randomY = randomNormal(0, 100); - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'line', - name: 'Line series', - data: new Array(25).fill(null).map((_, index) => ({ - x: index, - y: Math.abs(randomY()), - })), - }, - ], - }, - }; - const lineWidgetData: ChartKitWidgetData = {...widgetData, title: {text: 'line'}}; - const logarithmicWidgetData: ChartKitWidgetData = { - ...widgetData, - title: {text: 'logarithmic'}, - yAxis: [ - { - type: 'logarithmic', - }, - ], - }; - - return ( - - - logarithmic VS line - - - - - - - - - - - - - - - ); -}; diff --git a/src/plugins/d3/examples/line/Shapes.tsx b/src/plugins/d3/examples/line/Shapes.tsx deleted file mode 100644 index d9f23ddf..00000000 --- a/src/plugins/d3/examples/line/Shapes.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import {DashStyle} from '../../../../constants'; -import {ChartKitWidgetData, LineSeries, LineSeriesData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -const SHAPES = { - [DashStyle.Solid]: 1, - [DashStyle.Dash]: 2, - [DashStyle.Dot]: 3, - [DashStyle.ShortDashDot]: 4, - [DashStyle.LongDash]: 5, - [DashStyle.LongDashDot]: 6, - [DashStyle.ShortDot]: 7, - [DashStyle.LongDashDotDot]: 8, - [DashStyle.ShortDash]: 9, - [DashStyle.DashDot]: 10, - [DashStyle.ShortDashDotDot]: 11, -}; - -const selectShapes = (): DashStyle[] => Object.values(DashStyle); -const getShapesOrder = () => selectShapes().sort((a, b) => SHAPES[a] - SHAPES[b]); - -const SHAPES_IN_ORDER = getShapesOrder(); - -function prepareData(): ChartKitWidgetData { - const games = nintendoGames.filter((d) => { - return d.date && d.user_score; - }); - - const byGenre = (genre: string) => { - return games - .filter((d) => d.genres.includes(genre)) - .map((d) => { - return { - x: d.date, - y: d.user_score, - label: d.title, - }; - }) as LineSeriesData[]; - }; - - return { - series: { - options: { - line: { - lineWidth: 2, - }, - }, - data: [ - { - name: '3D', - type: 'line', - data: byGenre('3D'), - }, - { - name: '2D', - type: 'line', - data: byGenre('2D'), - }, - { - name: 'Strategy', - type: 'line', - data: byGenre('Strategy'), - }, - { - name: 'Shooter', - type: 'line', - data: byGenre('Shooter'), - }, - ], - }, - xAxis: { - type: 'datetime', - title: { - text: 'Release date', - }, - }, - yAxis: [ - { - title: {text: 'User score'}, - labels: { - enabled: true, - }, - ticks: { - pixelInterval: 120, - }, - }, - ], - }; -} - -export const LinesWithShapes = () => { - const data = prepareData(); - - (data.series.data as LineSeries[]).forEach((graph, i) => { - graph.dashStyle = SHAPES_IN_ORDER[i % SHAPES_IN_ORDER.length]; - }); - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/line/TwoYAxis.tsx b/src/plugins/d3/examples/line/TwoYAxis.tsx deleted file mode 100644 index 6545bb9c..00000000 --- a/src/plugins/d3/examples/line/TwoYAxis.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const TwoYAxis = () => { - const data = marsWeatherData as any[]; - const minTempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.min_temp, - })); - - const maxTempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.max_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'line', - data: minTempData, - name: 'Min Temperature', - yAxis: 0, - }, - { - type: 'line', - data: maxTempData, - name: 'Max Temperature', - yAxis: 1, - }, - ], - }, - yAxis: [ - { - title: { - text: 'Min', - }, - }, - { - title: { - text: 'Max', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - ticks: {pixelInterval: 200}, - }, - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/mars-weather.js b/src/plugins/d3/examples/mars-weather.js deleted file mode 100644 index 28f074ff..00000000 --- a/src/plugins/d3/examples/mars-weather.js +++ /dev/null @@ -1,1203 +0,0 @@ -// source: https://www.kaggle.com/datasets/thedevastator/mars-weather-data-from-2012-to-2018 -export default [ - { - id: '541', - terrestrial_date: '2014-04-14', - sol: 600, - ls: 116, - season: 'Month 4', - min_temp: -81, - max_temp: -25, - pressure: 787, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '543', - terrestrial_date: '2014-04-13', - sol: 599, - ls: 115, - season: 'Month 4', - min_temp: -84, - max_temp: -20, - pressure: 788, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '542', - terrestrial_date: '2014-04-12', - sol: 598, - ls: 115, - season: 'Month 4', - min_temp: -84, - max_temp: -25, - pressure: 787, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '540', - terrestrial_date: '2014-04-11', - sol: 597, - ls: 114, - season: 'Month 4', - min_temp: -84, - max_temp: -26, - pressure: 790, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '539', - terrestrial_date: '2014-04-10', - sol: 596, - ls: 114, - season: 'Month 4', - min_temp: -82, - max_temp: -24, - pressure: 791, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '538', - terrestrial_date: '2014-04-09', - sol: 595, - ls: 113, - season: 'Month 4', - min_temp: -83, - max_temp: -25, - pressure: 792, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '537', - terrestrial_date: '2014-04-08', - sol: 594, - ls: 113, - season: 'Month 4', - min_temp: -83, - max_temp: -22, - pressure: 793, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '536', - terrestrial_date: '2014-04-07', - sol: 593, - ls: 112, - season: 'Month 4', - min_temp: -83, - max_temp: -23, - pressure: 795, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '534', - terrestrial_date: '2014-04-06', - sol: 592, - ls: 112, - season: 'Month 4', - min_temp: -83, - max_temp: -26, - pressure: 795, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '533', - terrestrial_date: '2014-04-05', - sol: 591, - ls: 111, - season: 'Month 4', - min_temp: -82, - max_temp: -26, - pressure: 795, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '535', - terrestrial_date: '2014-04-04', - sol: 590, - ls: 111, - season: 'Month 4', - min_temp: -82, - max_temp: -26, - pressure: 797, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '531', - terrestrial_date: '2014-04-03', - sol: 589, - ls: 110, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 798, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '532', - terrestrial_date: '2014-04-02', - sol: 588, - ls: 110, - season: 'Month 4', - min_temp: -84, - max_temp: -24, - pressure: 799, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '530', - terrestrial_date: '2014-04-01', - sol: 587, - ls: 109, - season: 'Month 4', - min_temp: -85, - max_temp: -28, - pressure: 801, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '529', - terrestrial_date: '2014-03-31', - sol: 586, - ls: 109, - season: 'Month 4', - min_temp: -82, - max_temp: -24, - pressure: 802, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '527', - terrestrial_date: '2014-03-30', - sol: 585, - ls: 109, - season: 'Month 4', - min_temp: -83, - max_temp: -26, - pressure: 802, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '528', - terrestrial_date: '2014-03-29', - sol: 584, - ls: 108, - season: 'Month 4', - min_temp: -82, - max_temp: -25, - pressure: 804, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '526', - terrestrial_date: '2014-03-28', - sol: 583, - ls: 108, - season: 'Month 4', - min_temp: -82, - max_temp: -27, - pressure: 806, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '525', - terrestrial_date: '2014-03-27', - sol: 582, - ls: 107, - season: 'Month 4', - min_temp: -84, - max_temp: -27, - pressure: 807, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '524', - terrestrial_date: '2014-03-26', - sol: 581, - ls: 107, - season: 'Month 4', - min_temp: -84, - max_temp: -28, - pressure: 808, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '523', - terrestrial_date: '2014-03-25', - sol: 580, - ls: 106, - season: 'Month 4', - min_temp: -83, - max_temp: -24, - pressure: 810, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '522', - terrestrial_date: '2014-03-24', - sol: 579, - ls: 106, - season: 'Month 4', - min_temp: -82, - max_temp: -22, - pressure: 811, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '521', - terrestrial_date: '2014-03-22', - sol: 578, - ls: 105, - season: 'Month 4', - min_temp: -83, - max_temp: -23, - pressure: 812, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '519', - terrestrial_date: '2014-03-21', - sol: 577, - ls: 105, - season: 'Month 4', - min_temp: -84, - max_temp: -27, - pressure: 813, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '520', - terrestrial_date: '2014-03-20', - sol: 576, - ls: 104, - season: 'Month 4', - min_temp: -84, - max_temp: -26, - pressure: 815, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '518', - terrestrial_date: '2014-03-19', - sol: 575, - ls: 104, - season: 'Month 4', - min_temp: -82, - max_temp: -26, - pressure: 816, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '517', - terrestrial_date: '2014-03-18', - sol: 574, - ls: 103, - season: 'Month 4', - min_temp: -85, - max_temp: -23, - pressure: 817, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '516', - terrestrial_date: '2014-03-17', - sol: 573, - ls: 103, - season: 'Month 4', - min_temp: -84, - max_temp: -27, - pressure: 819, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '514', - terrestrial_date: '2014-03-16', - sol: 572, - ls: 102, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 820, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '515', - terrestrial_date: '2014-03-15', - sol: 571, - ls: 102, - season: 'Month 4', - min_temp: -84, - max_temp: -26, - pressure: 821, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '513', - terrestrial_date: '2014-03-14', - sol: 570, - ls: 102, - season: 'Month 4', - min_temp: -84, - max_temp: -26, - pressure: 823, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '512', - terrestrial_date: '2014-03-13', - sol: 569, - ls: 101, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 825, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '511', - terrestrial_date: '2014-03-12', - sol: 568, - ls: 101, - season: 'Month 4', - min_temp: -86, - max_temp: -28, - pressure: 825, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '510', - terrestrial_date: '2014-03-11', - sol: 567, - ls: 100, - season: 'Month 4', - min_temp: -86, - max_temp: -28, - pressure: 827, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '507', - terrestrial_date: '2014-03-10', - sol: 566, - ls: 100, - season: 'Month 4', - min_temp: -86, - max_temp: -27, - pressure: 829, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '508', - terrestrial_date: '2014-03-09', - sol: 565, - ls: 99, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 830, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '509', - terrestrial_date: '2014-03-08', - sol: 564, - ls: 99, - season: 'Month 4', - min_temp: -86, - max_temp: -27, - pressure: 831, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '505', - terrestrial_date: '2014-03-07', - sol: 563, - ls: 98, - season: 'Month 4', - min_temp: -87, - max_temp: -31, - pressure: 833, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '506', - terrestrial_date: '2014-03-06', - sol: 562, - ls: 98, - season: 'Month 4', - min_temp: -85, - max_temp: -23, - pressure: 834, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '504', - terrestrial_date: '2014-03-05', - sol: 561, - ls: 97, - season: 'Month 4', - min_temp: -85, - max_temp: -23, - pressure: 835, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '503', - terrestrial_date: '2014-03-04', - sol: 560, - ls: 97, - season: 'Month 4', - min_temp: -86, - max_temp: -23, - pressure: 836, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '502', - terrestrial_date: '2014-03-03', - sol: 559, - ls: 96, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 838, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '500', - terrestrial_date: '2014-03-02', - sol: 558, - ls: 96, - season: 'Month 4', - min_temp: -85, - max_temp: -26, - pressure: 839, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '498', - terrestrial_date: '2014-03-01', - sol: 557, - ls: 96, - season: 'Month 4', - min_temp: -85, - max_temp: -29, - pressure: 840, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '501', - terrestrial_date: '2014-02-28', - sol: 556, - ls: 95, - season: 'Month 4', - min_temp: -85, - max_temp: -29, - pressure: 842, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '499', - terrestrial_date: '2014-02-27', - sol: 555, - ls: 95, - season: 'Month 4', - min_temp: -85, - max_temp: -31, - pressure: 843, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '497', - terrestrial_date: '2014-02-26', - sol: 554, - ls: 94, - season: 'Month 4', - min_temp: -84, - max_temp: -22, - pressure: 843, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '496', - terrestrial_date: '2014-02-25', - sol: 553, - ls: 94, - season: 'Month 4', - min_temp: -84, - max_temp: -26, - pressure: 845, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '493', - terrestrial_date: '2014-02-24', - sol: 552, - ls: 93, - season: 'Month 4', - min_temp: -86, - max_temp: -29, - pressure: 847, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '495', - terrestrial_date: '2014-02-23', - sol: 551, - ls: 93, - season: 'Month 4', - min_temp: -85, - max_temp: -28, - pressure: 848, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '494', - terrestrial_date: '2014-02-22', - sol: 550, - ls: 92, - season: 'Month 4', - min_temp: -85, - max_temp: -27, - pressure: 850, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '492', - terrestrial_date: '2014-02-21', - sol: 549, - ls: 92, - season: 'Month 4', - min_temp: -87, - max_temp: -23, - pressure: 851, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '491', - terrestrial_date: '2014-02-20', - sol: 548, - ls: 91, - season: 'Month 4', - min_temp: -86, - max_temp: -28, - pressure: 852, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '488', - terrestrial_date: '2014-02-19', - sol: 547, - ls: 91, - season: 'Month 4', - min_temp: -85, - max_temp: -29, - pressure: 853, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '489', - terrestrial_date: '2014-02-18', - sol: 546, - ls: 91, - season: 'Month 4', - min_temp: -85, - max_temp: -34, - pressure: 855, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '490', - terrestrial_date: '2014-02-17', - sol: 545, - ls: 90, - season: 'Month 4', - min_temp: -85, - max_temp: -29, - pressure: 856, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '487', - terrestrial_date: '2014-02-16', - sol: 544, - ls: 90, - season: 'Month 4', - min_temp: -86, - max_temp: -27, - pressure: 857, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '486', - terrestrial_date: '2014-02-15', - sol: 543, - ls: 89, - season: 'Month 3', - min_temp: -84, - max_temp: -26, - pressure: 858, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '477', - terrestrial_date: '2014-02-13', - sol: 542, - ls: 89, - season: 'Month 3', - min_temp: -85, - max_temp: -28, - pressure: 859, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '482', - terrestrial_date: '2014-02-12', - sol: 541, - ls: 88, - season: 'Month 3', - min_temp: -84, - max_temp: -27, - pressure: 861, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '481', - terrestrial_date: '2014-02-11', - sol: 540, - ls: 88, - season: 'Month 3', - min_temp: -84, - max_temp: -29, - pressure: 862, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '476', - terrestrial_date: '2014-02-10', - sol: 539, - ls: 87, - season: 'Month 3', - min_temp: -85, - max_temp: -23, - pressure: 864, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '472', - terrestrial_date: '2014-02-09', - sol: 538, - ls: 87, - season: 'Month 3', - min_temp: -85, - max_temp: -25, - pressure: 865, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '469', - terrestrial_date: '2014-02-08', - sol: 537, - ls: 86, - season: 'Month 3', - min_temp: -83, - max_temp: -28, - pressure: 865, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '470', - terrestrial_date: '2014-02-07', - sol: 536, - ls: 86, - season: 'Month 3', - min_temp: -83, - max_temp: -29, - pressure: 867, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '468', - terrestrial_date: '2014-02-06', - sol: 535, - ls: 86, - season: 'Month 3', - min_temp: -88, - max_temp: -29, - pressure: 868, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '467', - terrestrial_date: '2014-02-05', - sol: 534, - ls: 85, - season: 'Month 3', - min_temp: -86, - max_temp: -29, - pressure: 869, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '466', - terrestrial_date: '2014-02-04', - sol: 533, - ls: 85, - season: 'Month 3', - min_temp: -87, - max_temp: -30, - pressure: 871, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '464', - terrestrial_date: '2014-02-03', - sol: 532, - ls: 84, - season: 'Month 3', - min_temp: -88, - max_temp: -23, - pressure: 872, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '465', - terrestrial_date: '2014-02-02', - sol: 531, - ls: 84, - season: 'Month 3', - min_temp: -87, - max_temp: -22, - pressure: 872, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '463', - terrestrial_date: '2014-02-01', - sol: 530, - ls: 83, - season: 'Month 3', - min_temp: -87, - max_temp: -28, - pressure: 873, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '462', - terrestrial_date: '2014-01-31', - sol: 529, - ls: 83, - season: 'Month 3', - min_temp: -87, - max_temp: -23, - pressure: 875, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '461', - terrestrial_date: '2014-01-30', - sol: 528, - ls: 82, - season: 'Month 3', - min_temp: -86, - max_temp: -26, - pressure: 876, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '460', - terrestrial_date: '2014-01-29', - sol: 527, - ls: 82, - season: 'Month 3', - min_temp: -86, - max_temp: -23, - pressure: 877, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '459', - terrestrial_date: '2014-01-28', - sol: 526, - ls: 82, - season: 'Month 3', - min_temp: -87, - max_temp: -24, - pressure: 878, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '456', - terrestrial_date: '2014-01-27', - sol: 525, - ls: 81, - season: 'Month 3', - min_temp: -87, - max_temp: -29, - pressure: 878, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '457', - terrestrial_date: '2014-01-26', - sol: 524, - ls: 81, - season: 'Month 3', - min_temp: -85, - max_temp: -27, - pressure: 880, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '458', - terrestrial_date: '2014-01-25', - sol: 523, - ls: 80, - season: 'Month 3', - min_temp: -85, - max_temp: -25, - pressure: 881, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '455', - terrestrial_date: '2014-01-24', - sol: 522, - ls: 80, - season: 'Month 3', - min_temp: -85, - max_temp: -26, - pressure: 881, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '454', - terrestrial_date: '2014-01-23', - sol: 521, - ls: 79, - season: 'Month 3', - min_temp: -87, - max_temp: -26, - pressure: 882, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '453', - terrestrial_date: '2014-01-22', - sol: 520, - ls: 79, - season: 'Month 3', - min_temp: -86, - max_temp: -24, - pressure: 884, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '452', - terrestrial_date: '2014-01-21', - sol: 519, - ls: 78, - season: 'Month 3', - min_temp: -86, - max_temp: -25, - pressure: 884, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '451', - terrestrial_date: '2014-01-20', - sol: 518, - ls: 78, - season: 'Month 3', - min_temp: -85, - max_temp: -29, - pressure: 885, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '448', - terrestrial_date: '2014-01-19', - sol: 517, - ls: 77, - season: 'Month 3', - min_temp: -86, - max_temp: -27, - pressure: 885, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '449', - terrestrial_date: '2014-01-18', - sol: 516, - ls: 77, - season: 'Month 3', - min_temp: -86, - max_temp: -25, - pressure: 888, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '450', - terrestrial_date: '2014-01-17', - sol: 515, - ls: 77, - season: 'Month 3', - min_temp: -86, - max_temp: -23, - pressure: 888, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '447', - terrestrial_date: '2014-01-16', - sol: 514, - ls: 76, - season: 'Month 3', - min_temp: -86, - max_temp: -29, - pressure: 888, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '445', - terrestrial_date: '2014-01-15', - sol: 513, - ls: 76, - season: 'Month 3', - min_temp: -86, - max_temp: -29, - pressure: 889, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '444', - terrestrial_date: '2014-01-14', - sol: 512, - ls: 75, - season: 'Month 3', - min_temp: -86, - max_temp: -24, - pressure: 890, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '446', - terrestrial_date: '2014-01-13', - sol: 511, - ls: 75, - season: 'Month 3', - min_temp: -85, - max_temp: -31, - pressure: 892, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '441', - terrestrial_date: '2014-01-12', - sol: 510, - ls: 74, - season: 'Month 3', - min_temp: -85, - max_temp: -31, - pressure: 892, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '443', - terrestrial_date: '2014-01-11', - sol: 509, - ls: 74, - season: 'Month 3', - min_temp: -86, - max_temp: -30, - pressure: 895, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '442', - terrestrial_date: '2014-01-10', - sol: 508, - ls: 73, - season: 'Month 3', - min_temp: -83, - max_temp: -29, - pressure: 893, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '440', - terrestrial_date: '2014-01-09', - sol: 507, - ls: 73, - season: 'Month 3', - min_temp: -85, - max_temp: -25, - pressure: 894, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '439', - terrestrial_date: '2014-01-08', - sol: 506, - ls: 73, - season: 'Month 3', - min_temp: -86, - max_temp: -27, - pressure: 894, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '438', - terrestrial_date: '2014-01-06', - sol: 505, - ls: 72, - season: 'Month 3', - min_temp: -85, - max_temp: -29, - pressure: 895, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '436', - terrestrial_date: '2014-01-05', - sol: 504, - ls: 72, - season: 'Month 3', - min_temp: -85, - max_temp: -29, - pressure: 895, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '483', - terrestrial_date: '2014-01-04', - sol: 503, - ls: 71, - season: 'Month 3', - min_temp: -86, - max_temp: -28, - pressure: 897, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '437', - terrestrial_date: '2014-01-03', - sol: 502, - ls: 71, - season: 'Month 3', - min_temp: -87, - max_temp: -30, - pressure: 898, - wind_speed: null, - atmo_opacity: 'Sunny', - }, - { - id: '435', - terrestrial_date: '2014-01-02', - sol: 501, - ls: 70, - season: 'Month 3', - min_temp: -86, - max_temp: -28, - pressure: 898, - wind_speed: null, - atmo_opacity: 'Sunny', - }, -]; diff --git a/src/plugins/d3/examples/nintendoGames.js b/src/plugins/d3/examples/nintendoGames.js deleted file mode 100644 index ca5f1213..00000000 --- a/src/plugins/d3/examples/nintendoGames.js +++ /dev/null @@ -1,12264 +0,0 @@ -//source: https://www.kaggle.com/datasets/joebeachcapital/nintendo-games -export default [ - { - meta_score: null, - title: 'Super Mario RPG', - platform: 'Switch', - date: 1700172000000, - user_score: null, - link: '/game/switch/super-mario-rpg', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'WarioWare: Move It!', - platform: 'Switch', - date: 1698962400000, - user_score: null, - link: '/game/switch/warioware-move-it!', - esrb_rating: 'RP', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Super Mario Bros. Wonder', - platform: 'Switch', - date: 1697749200000, - user_score: null, - link: '/game/switch/super-mario-bros-wonder', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Detective Pikachu Returns', - platform: 'Switch', - date: 1696539600000, - user_score: null, - link: '/game/switch/detective-pikachu-returns', - esrb_rating: '', - developers: ['Creatures Inc.'], - genres: ['Adventure', '3D', 'Third-Person'], - }, - { - meta_score: null, - title: 'Fae Farm', - platform: 'Switch', - date: 1694120400000, - user_score: null, - link: '/game/switch/fae-farm', - esrb_rating: 'E10+', - developers: ['Phoenix Labs'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 87, - title: 'Pikmin 4', - platform: 'Switch', - date: 1689886800000, - user_score: 9, - link: '/game/switch/pikmin-4', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'General'], - }, - { - meta_score: null, - title: 'Pokemon Sleep', - platform: 'iOS', - date: 1689800400000, - user_score: null, - link: '/game/ios/pokemon-sleep', - esrb_rating: '', - developers: ['The Pokemon Company', 'Select Button'], - genres: ['Role-Playing', 'Miscellaneous', 'Application', 'Trainer'], - }, - { - meta_score: 74, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 5', - platform: 'Switch', - date: 1689109200000, - user_score: 7.6, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-5', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 56, - title: 'Everybody 1-2-Switch!', - platform: 'Switch', - date: 1688072400000, - user_score: 5.4, - link: '/game/switch/everybody-1-2-switch!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 82, - title: 'Pikmin 1', - platform: 'Switch', - date: 1687294800000, - user_score: 8.4, - link: '/game/switch/pikmin-1', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'General'], - }, - { - meta_score: 65, - title: 'Pikmin 2', - platform: 'Switch', - date: 1687294800000, - user_score: 8.6, - link: '/game/switch/pikmin-2', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'General'], - }, - { - meta_score: 80, - title: 'Pikmin 1 + 2', - platform: 'Switch', - date: 1687294800000, - user_score: 8.5, - link: '/game/switch/pikmin-1-+-2', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 96, - title: 'The Legend of Zelda: Tears of the Kingdom', - platform: 'Switch', - date: 1683838800000, - user_score: 8.2, - link: '/game/switch/the-legend-of-zelda-tears-of-the-kingdom', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 92, - title: 'Xenoblade Chronicles 3: Expansion Pass Wave 4 - Future Redeemed', - platform: 'Switch', - date: 1682370000000, - user_score: 8.8, - link: '/game/switch/xenoblade-chronicles-3-expansion-pass-wave-4---future-redeemed', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 82, - title: 'Advance Wars 1 + 2: Re-Boot Camp', - platform: 'Switch', - date: 1682024400000, - user_score: 8.1, - link: '/game/switch/advance-wars-1-+-2-re-boot-camp', - esrb_rating: 'E10+', - developers: ['Nintendo', 'WayForward'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Engage: Expansion Pass Wave 4', - platform: 'Switch', - date: 1680642000000, - user_score: null, - link: '/game/switch/fire-emblem-engage-expansion-pass-wave-4', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 81, - title: 'Bayonetta Origins: Cereza and the Lost Demon', - platform: 'Switch', - date: 1679004000000, - user_score: 8.6, - link: '/game/switch/bayonetta-origins-cereza-and-the-lost-demon', - esrb_rating: 'T', - developers: ['PlatinumGames'], - genres: ['Action Adventure', 'Linear'], - }, - { - meta_score: 86, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 4', - platform: 'Switch', - date: 1678312800000, - user_score: 7.8, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-4', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: null, - title: 'Fire Emblem Engage: Expansion Pass Wave 3', - platform: 'Switch', - date: 1678140000000, - user_score: null, - link: '/game/switch/fire-emblem-engage-expansion-pass-wave-3', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Splatoon 3: Expansion Pass Wave 1 - Inkopolis', - platform: 'Switch', - date: 1677535200000, - user_score: null, - link: '/game/switch/splatoon-3-expansion-pass-wave-1---inkopolis', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: 79, - title: "Kirby's Return to Dream Land Deluxe", - platform: 'Switch', - date: 1677189600000, - user_score: 8.8, - link: '/game/switch/kirbys-return-to-dream-land-deluxe', - esrb_rating: 'E10+', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 3: Expansion Pass Wave 3', - platform: 'Switch', - date: 1676412000000, - user_score: null, - link: '/game/switch/xenoblade-chronicles-3-expansion-pass-wave-3', - esrb_rating: '', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Fire Emblem Engage: Expansion Pass Wave 2', - platform: 'Switch', - date: 1675807200000, - user_score: null, - link: '/game/switch/fire-emblem-engage-expansion-pass-wave-2', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 94, - title: 'Metroid Prime Remastered', - platform: 'Switch', - date: 1675807200000, - user_score: 8.7, - link: '/game/switch/metroid-prime-remastered', - esrb_rating: 'T', - developers: ['Nintendo', 'Retro Studios', 'Iron Galaxy Studios'], - genres: ['Action', 'Shooter', 'First-Person', 'Arcade'], - }, - { - meta_score: 80, - title: 'Fire Emblem Engage', - platform: 'Switch', - date: 1674165600000, - user_score: 6.6, - link: '/game/switch/fire-emblem-engage', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Engage: Expansion Pass Wave 1', - platform: 'Switch', - date: 1674165600000, - user_score: null, - link: '/game/switch/fire-emblem-engage-expansion-pass-wave-1', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 83, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 3', - platform: 'Switch', - date: 1670364000000, - user_score: 7.3, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-3', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 71, - title: 'Pokemon Violet', - platform: 'Switch', - date: 1668722400000, - user_score: 4, - link: '/game/switch/pokemon-violet', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 72, - title: 'Pokemon Scarlet', - platform: 'Switch', - date: 1668722400000, - user_score: 3.4, - link: '/game/switch/pokemon-scarlet', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Pokemon Scarlet / Pokemon Violet Dual Pack Steelbook Edition', - platform: 'Switch', - date: 1668722400000, - user_score: 8, - link: '/game/switch/pokemon-scarlet-pokemon-violet-dual-pack-steelbook-edition', - esrb_rating: 'RP', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation', 'Role-Playing', 'Trainer'], - }, - { - meta_score: 86, - title: 'Bayonetta 3', - platform: 'Switch', - date: 1666904400000, - user_score: 7.1, - link: '/game/switch/bayonetta-3', - esrb_rating: 'M', - developers: ['PlatinumGames'], - genres: ['Action Adventure', 'Linear'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 3: Expansion Pass Wave 2', - platform: 'Switch', - date: 1665608400000, - user_score: null, - link: '/game/switch/xenoblade-chronicles-3-expansion-pass-wave-2', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 83, - title: 'Splatoon 3', - platform: 'Switch', - date: 1662670800000, - user_score: 6.8, - link: '/game/switch/splatoon-3', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: 67, - title: "Kirby's Dream Buffet", - platform: 'Switch', - date: 1660683600000, - user_score: 7.3, - link: '/game/switch/kirbys-dream-buffet', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 77, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 2', - platform: 'Switch', - date: 1659560400000, - user_score: 6.8, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-2', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 89, - title: 'Xenoblade Chronicles 3', - platform: 'Switch', - date: 1659042000000, - user_score: 8.5, - link: '/game/switch/xenoblade-chronicles-3', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 81, - title: 'Live A Live', - platform: 'Switch', - date: 1658437200000, - user_score: 7.5, - link: '/game/switch/live-a-live', - esrb_rating: 'T', - developers: ['Square Enix', 'historia Inc'], - genres: ['Role-Playing', 'Strategy', 'Turn-Based', 'Japanese-Style', 'Tactics'], - }, - { - meta_score: 80, - title: 'Fire Emblem Warriors: Three Hopes', - platform: 'Switch', - date: 1656018000000, - user_score: 8.9, - link: '/game/switch/fire-emblem-warriors-three-hopes', - esrb_rating: 'T', - developers: ['Nintendo', 'Koei Tecmo Games'], - genres: ['Strategy', 'Real-Time', 'General', 'Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 73, - title: 'Mario Strikers: Battle League', - platform: 'Switch', - date: 1654808400000, - user_score: 4.4, - link: '/game/switch/mario-strikers-battle-league', - esrb_rating: 'E10+', - developers: ['Next Level Games', 'Nintendo'], - genres: ['Sports', 'Team', 'Soccer', 'Arcade'], - }, - { - meta_score: 72, - title: 'Nintendo Switch Sports', - platform: 'Switch', - date: 1651179600000, - user_score: 5.9, - link: '/game/switch/nintendo-switch-sports', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Sports', 'General', 'Individual', 'Athletics'], - }, - { - meta_score: 85, - title: 'Kirby and the Forgotten Land', - platform: 'Switch', - date: 1648159200000, - user_score: 8.9, - link: '/game/switch/kirby-and-the-forgotten-land', - esrb_rating: 'E10+', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 73, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 1', - platform: 'Switch', - date: 1647554400000, - user_score: 6.8, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-1', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 83, - title: 'Pokemon Legends: Arceus', - platform: 'Switch', - date: 1643320800000, - user_score: 8.1, - link: '/game/switch/pokemon-legends-arceus', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 73, - title: 'Big Brain Academy: Brain vs. Brain', - platform: 'Switch', - date: 1638482400000, - user_score: 8.1, - link: '/game/switch/big-brain-academy-brain-vs-brain', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 69, - title: 'Disney Magical World 2: Enchanted Edition', - platform: 'Switch', - date: 1638482400000, - user_score: 7, - link: '/game/switch/disney-magical-world-2-enchanted-edition', - esrb_rating: 'E', - developers: ['h.a.n.d. Inc.'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 73, - title: 'Pokemon Brilliant Diamond', - platform: 'Switch', - date: 1637272800000, - user_score: 5.3, - link: '/game/switch/pokemon-brilliant-diamond', - esrb_rating: 'E', - developers: ['ILCA', 'Inc.'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 73, - title: 'Pokemon Shining Pearl', - platform: 'Switch', - date: 1637272800000, - user_score: 5.5, - link: '/game/switch/pokemon-shining-pearl', - esrb_rating: 'E', - developers: ['ILCA', 'Inc.'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Pokemon Brilliant Diamond / Pokemon Shining Pearl Double Pack', - platform: 'Switch', - date: 1637272800000, - user_score: 6.4, - link: '/game/switch/pokemon-brilliant-diamond-pokemon-shining-pearl-double-pack', - esrb_rating: 'E', - developers: ['ILCA', 'Inc.'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 82, - title: 'Animal Crossing: New Horizons - Happy Home Paradise', - platform: 'Switch', - date: 1636063200000, - user_score: 7.9, - link: '/game/switch/animal-crossing-new-horizons---happy-home-paradise', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 80, - title: 'Mario Party Superstars', - platform: 'Switch', - date: 1635454800000, - user_score: 8, - link: '/game/switch/mario-party-superstars', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Hyrule Warriors: Age of Calamity - Guardian of Remembrance', - platform: 'Switch', - date: 1635454800000, - user_score: null, - link: '/game/switch/hyrule-warriors-age-of-calamity---guardian-of-remembrance', - esrb_rating: '', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 65, - title: 'Pikmin Bloom', - platform: 'iOS', - date: 1635368400000, - user_score: 6, - link: '/game/ios/pikmin-bloom', - esrb_rating: '', - developers: ['Niantic Tokyo Studio'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Minecraft Dungeons: Ultimate Edition', - platform: 'Switch', - date: 1635195600000, - user_score: 7.1, - link: '/game/switch/minecraft-dungeons-ultimate-edition', - esrb_rating: '', - developers: ['Nintendo', 'Mojang AB'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Sora', - platform: 'Switch', - date: 1634504400000, - user_score: 6.8, - link: '/game/switch/super-smash-bros-ultimate-sora', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 88, - title: 'Metroid Dread', - platform: 'Switch', - date: 1633640400000, - user_score: 8.7, - link: '/game/switch/metroid-dread', - esrb_rating: 'T', - developers: ['Mercury Steam', 'Nintendo'], - genres: ['Action', 'Action Adventure', 'Platformer', 'Open-World', '', 'Metroidvania'], - }, - { - meta_score: 76, - title: 'WarioWare: Get It Together!', - platform: 'Switch', - date: 1631221200000, - user_score: 7.7, - link: '/game/switch/warioware-get-it-together!', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Intelligent Systems'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 81, - title: 'The Legend of Zelda: Skyward Sword HD', - platform: 'Switch', - date: 1626382800000, - user_score: 7.3, - link: '/game/switch/the-legend-of-zelda-skyward-sword-hd', - esrb_rating: 'E10+', - developers: ['Tantalus', 'Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: null, - title: 'Fitness Boxing 2: Rhythm & Exercise - Musical Journey', - platform: 'Switch', - date: 1625086800000, - user_score: null, - link: '/game/switch/fitness-boxing-2-rhythm-exercise---musical-journey', - esrb_rating: '', - developers: ['Jupiter Corporation'], - genres: ['Miscellaneous', 'Exercise / Fitness'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Kazuya', - platform: 'Switch', - date: 1624914000000, - user_score: null, - link: '/game/switch/super-smash-bros-ultimate-kazuya', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 70, - title: 'Mario Golf: Super Rush', - platform: 'Switch', - date: 1624568400000, - user_score: 5.5, - link: '/game/switch/mario-golf-super-rush', - esrb_rating: 'E', - developers: ['Nintendo', 'Camelot Software Planning'], - genres: ['Sports', 'Individual', 'Golf', 'Arcade'], - }, - { - meta_score: 67, - title: 'Hyrule Warriors: Age of Calamity - Pulse of the Ancients', - platform: 'Switch', - date: 1623963600000, - user_score: 8.2, - link: '/game/switch/hyrule-warriors-age-of-calamity---pulse-of-the-ancients', - esrb_rating: '', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 77, - title: 'Game Builder Garage', - platform: 'Switch', - date: 1623358800000, - user_score: 7.8, - link: '/game/switch/game-builder-garage', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: 66, - title: 'DC Super Hero Girls: Teen Power', - platform: 'Switch', - date: 1622754000000, - user_score: 6.7, - link: '/game/switch/dc-super-hero-girls-teen-power', - esrb_rating: 'E10+', - developers: ['Nintendo', 'TOYBOX'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 71, - title: 'Miitopia', - platform: 'Switch', - date: 1621544400000, - user_score: 8.1, - link: '/game/switch/miitopia', - esrb_rating: 'E', - developers: ['Nintendo', 'GREZZO'], - genres: ['Action', 'Role-Playing', 'General'], - }, - { - meta_score: 74, - title: 'Famicom Detective Club: The Missing Heir', - platform: 'Switch', - date: 1620939600000, - user_score: 7.1, - link: '/game/switch/famicom-detective-club-the-missing-heir', - esrb_rating: 'T', - developers: ['Nintendo', 'Mages.'], - genres: ['Adventure', 'Visual Novel'], - }, - { - meta_score: 74, - title: 'Famicom Detective Club: The Girl Who Stands Behind', - platform: 'Switch', - date: 1620939600000, - user_score: 7.1, - link: '/game/switch/famicom-detective-club-the-girl-who-stands-behind', - esrb_rating: 'T', - developers: ['Nintendo', 'Mages.'], - genres: ['Adventure', 'Visual Novel'], - }, - { - meta_score: 79, - title: 'New Pokemon Snap', - platform: 'Switch', - date: 1619730000000, - user_score: 6.9, - link: '/game/switch/new-pokemon-snap', - esrb_rating: 'E', - developers: ['Bandai Namco Games', 'The Pokemon Company'], - genres: ['Action', 'Shooter', 'Rail'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Pyra / Mythra', - platform: 'Switch', - date: 1614808800000, - user_score: 7.7, - link: '/game/switch/super-smash-bros-ultimate-pyra-mythra', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'Project Triangle Strategy Debut Demo', - platform: 'Switch', - date: 1613512800000, - user_score: null, - link: '/game/switch/project-triangle-strategy-debut-demo', - esrb_rating: '', - developers: ['Square Enix', 'Nintendo'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 89, - title: "Super Mario 3D World + Bowser's Fury", - platform: 'Switch', - date: 1613080800000, - user_score: 8.7, - link: '/game/switch/super-mario-3d-world-+-bowsers-fury', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Sephiroth', - platform: 'Switch', - date: 1608588000000, - user_score: 7.7, - link: '/game/switch/super-smash-bros-ultimate-sephiroth', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 66, - title: 'Fitness Boxing 2: Rhythm & Exercise', - platform: 'Switch', - date: 1607032800000, - user_score: 5.7, - link: '/game/switch/fitness-boxing-2-rhythm-exercise', - esrb_rating: 'E', - developers: ['Nintendo', 'Jupiter Corporation', 'Imagineer Co.', 'Ltd.'], - genres: ['Miscellaneous', 'Exercise / Fitness'], - }, - { - meta_score: 63, - title: 'Fire Emblem: Shadow Dragon & the Blade of Light', - platform: 'Switch', - date: 1607032800000, - user_score: 7.8, - link: '/game/switch/fire-emblem-shadow-dragon-the-blade-of-light', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 78, - title: 'Hyrule Warriors: Age of Calamity', - platform: 'Switch', - date: 1605823200000, - user_score: 8, - link: '/game/switch/hyrule-warriors-age-of-calamity', - esrb_rating: 'T', - developers: ['Omega Force', 'Koei Tecmo Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Pokemon Sword + Pokemon Sword Expansion Pass', - platform: 'Switch', - date: 1604613600000, - user_score: 6.5, - link: '/game/switch/pokemon-sword-+-pokemon-sword-expansion-pass', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Pokemon Shield + Pokemon Shield Expansion Pass', - platform: 'Switch', - date: 1604613600000, - user_score: 6.4, - link: '/game/switch/pokemon-shield-+-pokemon-shield-expansion-pass', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 85, - title: 'Pikmin 3 Deluxe', - platform: 'Switch', - date: 1604008800000, - user_score: 8.6, - link: '/game/switch/pikmin-3-deluxe', - esrb_rating: 'E10+', - developers: ['Eighting', 'Nintendo'], - genres: ['Strategy', 'Real-Time', 'General'], - }, - { - meta_score: 78, - title: 'Part Time UFO', - platform: 'Switch', - date: 1603836000000, - user_score: 7.5, - link: '/game/switch/part-time-ufo', - esrb_rating: 'E10+', - developers: ['HAL Labs'], - genres: ['Action', 'Arcade'], - }, - { - meta_score: null, - title: 'Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda - Complete Edition', - platform: 'Switch', - date: 1603400400000, - user_score: 8.8, - link: '/game/switch/cadence-of-hyrule-crypt-of-the-necrodancer-featuring-the-legend-of-zelda---complete-edition', - esrb_rating: 'E', - developers: ['Brace Yourself Games'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: 75, - title: 'Pokemon Sword / Shield: The Crown Tundra', - platform: 'Switch', - date: 1603314000000, - user_score: 7.1, - link: '/game/switch/pokemon-sword-shield-the-crown-tundra', - esrb_rating: '', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 75, - title: 'Mario Kart Live: Home Circuit', - platform: 'Switch', - date: 1602795600000, - user_score: 7.1, - link: '/game/switch/mario-kart-live-home-circuit', - esrb_rating: 'E', - developers: ['Nintendo', 'Velan Studios'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Steve & Alex', - platform: 'Switch', - date: 1602536400000, - user_score: 7.6, - link: '/game/switch/super-smash-bros-ultimate-steve-alex', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'Mario Kart 8 Deluxe + Super Mario Party', - platform: 'Switch', - date: 1601758800000, - user_score: null, - link: '/game/switch/mario-kart-8-deluxe-+-super-mario-party', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 75, - title: 'Super Mario Bros. 35', - platform: 'Switch', - date: 1601499600000, - user_score: 7.6, - link: '/game/switch/super-mario-bros-35', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda - DLC 3 Story Pack: Symphony of the Mask', - platform: 'Switch', - date: 1600808400000, - user_score: null, - link: '/game/switch/cadence-of-hyrule-crypt-of-the-necrodancer-featuring-the-legend-of-zelda---dlc-3-story-pack-symphony-of-the-mask', - esrb_rating: 'E', - developers: ['Brace Yourself Games'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: 65, - title: 'Kirby Fighters 2', - platform: 'Switch', - date: 1600808400000, - user_score: 7.9, - link: '/game/switch/kirby-fighters-2', - esrb_rating: 'E', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 82, - title: 'Super Mario 3D All-Stars', - platform: 'Switch', - date: 1600376400000, - user_score: 6.4, - link: '/game/switch/super-mario-3d-all-stars', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: null, - title: 'Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda - DLC 2 Melody Pack', - platform: 'Switch', - date: 1598389200000, - user_score: null, - link: '/game/switch/cadence-of-hyrule-crypt-of-the-necrodancer-featuring-the-legend-of-zelda---dlc-2-melody-pack', - esrb_rating: 'E', - developers: ['Brace Yourself Games'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: null, - title: 'Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda - DLC 1 Character Pack', - platform: 'Switch', - date: 1595192400000, - user_score: null, - link: '/game/switch/cadence-of-hyrule-crypt-of-the-necrodancer-featuring-the-legend-of-zelda---dlc-1-character-pack', - esrb_rating: 'E', - developers: ['Brace Yourself Games'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: 80, - title: 'Paper Mario: The Origami King', - platform: 'Switch', - date: 1594933200000, - user_score: 7, - link: '/game/switch/paper-mario-the-origami-king', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Role-Playing', 'General'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Min Min', - platform: 'Switch', - date: 1593378000000, - user_score: 8.2, - link: '/game/switch/super-smash-bros-ultimate-min-min', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 64, - title: 'Pokemon Cafe Mix', - platform: 'Switch', - date: 1592859600000, - user_score: 6.2, - link: '/game/switch/pokemon-cafe-mix', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.', 'The Pokemon Company'], - genres: ['Puzzle', 'Matching'], - }, - { - meta_score: 69, - title: 'Pokemon Sword / Shield: The Isle of Armor', - platform: 'Switch', - date: 1592341200000, - user_score: 5.2, - link: '/game/switch/pokemon-sword-shield-the-isle-of-armor', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Jump Rope Challenge', - platform: 'Switch', - date: 1592168400000, - user_score: 6.9, - link: '/game/switch/jump-rope-challenge', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'Miscellaneous', 'Exercise / Fitness'], - }, - { - meta_score: 82, - title: 'Clubhouse Games: 51 Worldwide Classics', - platform: 'Switch', - date: 1591304400000, - user_score: 7.7, - link: '/game/switch/clubhouse-games-51-worldwide-classics', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 89, - title: 'Xenoblade Chronicles: Definitive Edition', - platform: 'Switch', - date: 1590699600000, - user_score: 8.8, - link: '/game/switch/xenoblade-chronicles-definitive-edition', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Arcade Archives: Vs. Wrecking Crew', - platform: 'Switch', - date: 1588280400000, - user_score: null, - link: '/game/switch/arcade-archives-vs-wrecking-crew', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Marvel Ultimate Alliance 3: The Black Order - Expansion 3 - Fantastic Four: Shadow of Doom', - platform: 'Switch', - date: 1585173600000, - user_score: 7.9, - link: '/game/switch/marvel-ultimate-alliance-3-the-black-order---expansion-3---fantastic-four-shadow-of-doom', - esrb_rating: 'T', - developers: ['Team Ninja'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 78, - title: 'Good Job!', - platform: 'Switch', - date: 1585173600000, - user_score: 8, - link: '/game/switch/good-job!', - esrb_rating: 'E', - developers: ['Nintendo', 'Paladin Studios'], - genres: ['Puzzle', 'Action', 'General'], - }, - { - meta_score: 90, - title: 'Animal Crossing: New Horizons', - platform: 'Switch', - date: 1584655200000, - user_score: 5.6, - link: '/game/switch/animal-crossing-new-horizons', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 69, - title: 'Pokemon Mystery Dungeon: Rescue Team DX', - platform: 'Switch', - date: 1583445600000, - user_score: 8.1, - link: '/game/switch/pokemon-mystery-dungeon-rescue-team-dx', - esrb_rating: 'E', - developers: ['Spike Chunsoft'], - genres: ['Role-Playing', 'Roguelike'], - }, - { - meta_score: null, - title: "Luigi's Mansion 3: Multiplayer Pack 1 & 2", - platform: 'Switch', - date: 1583272800000, - user_score: null, - link: '/game/switch/luigis-mansion-3-multiplayer-pack-1-2', - esrb_rating: '', - developers: ['Next Level Games'], - genres: ['Action Adventure', 'General'], - }, - { - meta_score: 75, - title: 'Fire Emblem: Three Houses - Side Story: Cindered Shadows', - platform: 'Switch', - date: 1581544800000, - user_score: 8.1, - link: '/game/switch/fire-emblem-three-houses---side-story-cindered-shadows', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Pokemon HOME', - platform: 'iOS', - date: 1581372000000, - user_score: 3.9, - link: '/game/ios/pokemon-home', - esrb_rating: '', - developers: ['Game Freak', 'ILCA', 'Inc.'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: null, - title: 'Pokemon HOME', - platform: 'Switch', - date: 1581372000000, - user_score: 3.1, - link: '/game/switch/pokemon-home', - esrb_rating: 'E', - developers: ['Game Freak', 'ILCA', 'Inc.'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Byleth', - platform: 'Switch', - date: 1580162400000, - user_score: 7.1, - link: '/game/switch/super-smash-bros-ultimate-byleth', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 81, - title: 'Tokyo Mirage Sessions #FE Encore', - platform: 'Switch', - date: 1579212000000, - user_score: 6.2, - link: '/game/switch/tokyo-mirage-sessions-fe-encore', - esrb_rating: 'T', - developers: ['Atlus'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 64, - title: "Dr. Kawashima's Brain Training for Nintendo Switch", - platform: 'Switch', - date: 1578002400000, - user_score: 6.4, - link: '/game/switch/dr-kawashimas-brain-training-for-nintendo-switch', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment'], - }, - { - meta_score: null, - title: 'Arcade Archives: Vs. Balloon Fight', - platform: 'Switch', - date: 1577397600000, - user_score: null, - link: '/game/switch/arcade-archives-vs-balloon-fight', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Arcade'], - }, - { - meta_score: null, - title: 'Marvel Ultimate Alliance 3: The Black Order - Expansion 2: Rise of the Phoenix', - platform: 'Switch', - date: 1577052000000, - user_score: null, - link: '/game/switch/marvel-ultimate-alliance-3-the-black-order---expansion-2-rise-of-the-phoenix', - esrb_rating: 'T', - developers: ['Team Ninja'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 80, - title: 'Pokemon Shield', - platform: 'Switch', - date: 1573768800000, - user_score: 4.7, - link: '/game/switch/pokemon-shield', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 80, - title: 'Pokemon Sword', - platform: 'Switch', - date: 1573768800000, - user_score: 4.7, - link: '/game/switch/pokemon-sword', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 80, - title: 'Pokemon Sword / Shield Dual Pack', - platform: 'Switch', - date: 1573768800000, - user_score: 4.4, - link: '/game/switch/pokemon-sword-shield-dual-pack', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 73, - title: "Layton's Mystery Journey: Katrielle and The Millionaires'Conspiracy - Deluxe Edition", - platform: 'Switch', - date: 1573164000000, - user_score: 6.8, - link: '/game/switch/laytons-mystery-journey-katrielle-and-the-millionaires-conspiracy---deluxe-edition', - esrb_rating: 'E10+', - developers: ['Level 5', 'h.a.n.d. Inc.'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: 75, - title: 'The Stretchers', - platform: 'Switch', - date: 1573164000000, - user_score: 7.2, - link: '/game/switch/the-stretchers', - esrb_rating: 'E', - developers: ['Tarsier Studios'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Terry Bogard', - platform: 'Switch', - date: 1572991200000, - user_score: 7.6, - link: '/game/switch/super-smash-bros-ultimate-terry-bogard', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 86, - title: "Luigi's Mansion 3", - platform: 'Switch', - date: 1572472800000, - user_score: 8.4, - link: '/game/switch/luigis-mansion-3', - esrb_rating: 'E', - developers: ['Next Level Games', 'Nintendo'], - genres: ['Action Adventure', 'General'], - }, - { - meta_score: 83, - title: 'Ring Fit Adventure', - platform: 'Switch', - date: 1571346000000, - user_score: 8.6, - link: '/game/switch/ring-fit-adventure', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Exercise / Fitness'], - }, - { - meta_score: 64, - title: 'Little Town Hero', - platform: 'Switch', - date: 1571173200000, - user_score: 4.7, - link: '/game/switch/little-town-hero', - esrb_rating: 'E10+', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Marvel Ultimate Alliance 3: The Black Order - Expansion 1: Curse of the Vampire', - platform: 'Switch', - date: 1569790800000, - user_score: null, - link: '/game/switch/marvel-ultimate-alliance-3-the-black-order---expansion-1-curse-of-the-vampire', - esrb_rating: 'T', - developers: ['Team Ninja'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 91, - title: 'Dragon Quest XI S: Echoes of an Elusive Age - Definitive Edition', - platform: 'Switch', - date: 1569531600000, - user_score: 8.6, - link: '/game/switch/dragon-quest-xi-s-echoes-of-an-elusive-age---definitive-edition', - esrb_rating: 'T', - developers: ['Square Enix'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 59, - title: 'Mario Kart Tour', - platform: 'iOS', - date: 1569358800000, - user_score: 4.2, - link: '/game/ios/mario-kart-tour', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 87, - title: "The Legend of Zelda: Link's Awakening", - platform: 'Switch', - date: 1568926800000, - user_score: 8.4, - link: '/game/switch/the-legend-of-zelda-links-awakening', - esrb_rating: 'E', - developers: ['Nintendo', 'GREZZO'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 69, - title: 'Daemon X Machina', - platform: 'Switch', - date: 1568322000000, - user_score: 7.6, - link: '/game/switch/daemon-x-machina', - esrb_rating: 'T', - developers: ['First Studio', 'Marvelous First Studio'], - genres: ['Simulation', 'Vehicle', 'Combat'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Banjo & Kazooie', - platform: 'Switch', - date: 1567544400000, - user_score: 8.1, - link: '/game/switch/super-smash-bros-ultimate-banjo-kazooie', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 74, - title: 'Super Kirby Clash', - platform: 'Switch', - date: 1567544400000, - user_score: 7.5, - link: '/game/switch/super-kirby-clash', - esrb_rating: 'E', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Arcade Archives: Pinball', - platform: 'Switch', - date: 1567112400000, - user_score: null, - link: '/game/switch/arcade-archives-pinball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Pinball'], - }, - { - meta_score: 87, - title: 'Astral Chain', - platform: 'Switch', - date: 1567112400000, - user_score: 8.9, - link: '/game/switch/astral-chain', - esrb_rating: 'T', - developers: ['PlatinumGames'], - genres: ['Action Adventure', 'General'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Hero', - platform: 'Switch', - date: 1564434000000, - user_score: 7.8, - link: '/game/switch/super-smash-bros-ultimate-hero', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 89, - title: 'Fire Emblem: Three Houses', - platform: 'Switch', - date: 1564088400000, - user_score: 8.8, - link: '/game/switch/fire-emblem-three-houses', - esrb_rating: 'T', - developers: ['Intelligent Systems', 'Koei Tecmo Games'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 73, - title: 'Marvel Ultimate Alliance 3: The Black Order', - platform: 'Switch', - date: 1563483600000, - user_score: 7.3, - link: '/game/switch/marvel-ultimate-alliance-3-the-black-order', - esrb_rating: 'T', - developers: ['Team Ninja'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 58, - title: 'Dr. Mario World', - platform: 'iOS', - date: 1562706000000, - user_score: 3.4, - link: '/game/ios/dr-mario-world', - esrb_rating: '', - developers: ['Nintendo', 'LINE Corporation'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: null, - title: 'Arcade Archives: Clu Clu Land', - platform: 'Switch', - date: 1561669200000, - user_score: null, - link: '/game/switch/arcade-archives-clu-clu-land', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Arcade'], - }, - { - meta_score: 88, - title: 'Super Mario Maker 2', - platform: 'Switch', - date: 1561669200000, - user_score: 8.5, - link: '/game/switch/super-mario-maker-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 85, - title: 'Cadence of Hyrule: Crypt of the NecroDancer Featuring The Legend of Zelda', - platform: 'Switch', - date: 1560373200000, - user_score: 8, - link: '/game/switch/cadence-of-hyrule-crypt-of-the-necrodancer-featuring-the-legend-of-zelda', - esrb_rating: 'E', - developers: ['Brace Yourself Games'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: 71, - title: 'Nintendo Labo: Toycon 04 VR Kit', - platform: 'Switch', - date: 1557608400000, - user_score: 6.6, - link: '/game/switch/nintendo-labo-toycon-04-vr-kit', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Tetris 99: Big Block', - platform: 'Switch', - date: 1557435600000, - user_score: 5.9, - link: '/game/switch/tetris-99-big-block', - esrb_rating: 'E', - developers: ['Arika'], - genres: ['Puzzle', 'Stacking'], - }, - { - meta_score: 81, - title: 'BoxBoy! + BoxGirl!', - platform: 'Switch', - date: 1556226000000, - user_score: 8, - link: '/game/switch/boxboy!-+-boxgirl!', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Joker', - platform: 'Switch', - date: 1555448400000, - user_score: 8.1, - link: '/game/switch/super-smash-bros-ultimate-joker', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 79, - title: "Yoshi's Crafted World", - platform: 'Switch', - date: 1553724000000, - user_score: 7.8, - link: '/game/switch/yoshis-crafted-world', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 81, - title: 'Captain Toad: Treasure Tracker - Special Episode', - platform: 'Switch', - date: 1552514400000, - user_score: 8.2, - link: '/game/switch/captain-toad-treasure-tracker---special-episode', - esrb_rating: '', - developers: ['Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', '3D'], - }, - { - meta_score: 79, - title: "Kirby's Extra Epic Yarn", - platform: '3DS', - date: 1551996000000, - user_score: 6.7, - link: '/game/3ds/kirbys-extra-epic-yarn', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Arcade Archives: Vs. Ice Climber', - platform: 'Switch', - date: 1550786400000, - user_score: 7.3, - link: '/game/switch/arcade-archives-vs-ice-climber', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 83, - title: 'Tetris 99', - platform: 'Switch', - date: 1550008800000, - user_score: 8.1, - link: '/game/switch/tetris-99', - esrb_rating: 'E', - developers: ['Arika', 'Nintendo'], - genres: ['Puzzle', 'Stacking'], - }, - { - meta_score: null, - title: 'Daemon X Machina: Prototype Missions', - platform: 'Switch', - date: 1550008800000, - user_score: 6.6, - link: '/game/switch/daemon-x-machina-prototype-missions', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Simulation', 'Vehicle', 'Combat'], - }, - { - meta_score: 80, - title: 'Yo-kai Watch 3', - platform: '3DS', - date: 1549576800000, - user_score: 8.4, - link: '/game/3ds/yo-kai-watch-3', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Super Smash Bros. Ultimate: Piranha Plant', - platform: 'Switch', - date: 1548712800000, - user_score: 7.1, - link: '/game/switch/super-smash-bros-ultimate-piranha-plant', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 67, - title: 'Travis Strikes Again: No More Heroes', - platform: 'Switch', - date: 1547762400000, - user_score: 7.8, - link: '/game/switch/travis-strikes-again-no-more-heroes', - esrb_rating: 'M', - developers: ['Grasshopper Manufacture'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 84, - title: "Mario & Luigi: Bowser's Inside Story + Bowser Jr.'s Journey", - platform: '3DS', - date: 1547157600000, - user_score: 7.8, - link: '/game/3ds/mario-luigi-bowsers-inside-story-+-bowser-jrs-journey', - esrb_rating: 'E', - developers: ['Nintendo', 'Alphadream Corporation'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 80, - title: 'New Super Mario Bros. U Deluxe', - platform: 'Switch', - date: 1547157600000, - user_score: 7, - link: '/game/switch/new-super-mario-bros-u-deluxe', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 66, - title: 'Fitness Boxing', - platform: 'Switch', - date: 1546552800000, - user_score: 6.5, - link: '/game/switch/fitness-boxing', - esrb_rating: 'T', - developers: ['Imagineer Co.', 'Ltd.'], - genres: ['Miscellaneous', 'Exercise / Fitness'], - }, - { - meta_score: 93, - title: 'Super Smash Bros. Ultimate', - platform: 'Switch', - date: 1544133600000, - user_score: 8.6, - link: '/game/switch/super-smash-bros-ultimate', - esrb_rating: 'E10+', - developers: ['Nintendo', 'HAL Labs', 'Bandai Namco Games', 'Sora Ltd.'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 80, - title: "Pokemon: Let's Go, Eevee!", - platform: 'Switch', - date: 1542319200000, - user_score: 6.4, - link: '/game/switch/pokemon-lets-go-eevee!', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Action RPG', 'Role-Playing', 'Trainer'], - }, - { - meta_score: 79, - title: "Pokemon: Let's Go, Pikachu!", - platform: 'Switch', - date: 1542319200000, - user_score: 6.3, - link: '/game/switch/pokemon-lets-go-pikachu!', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Action RPG', 'Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Arcade Archives: Urban Champion', - platform: 'Switch', - date: 1541714400000, - user_score: null, - link: '/game/switch/arcade-archives-urban-champion', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 77, - title: 'The World Ends with You: Final Remix', - platform: 'Switch', - date: 1539291600000, - user_score: 7.4, - link: '/game/switch/the-world-ends-with-you-final-remix', - esrb_rating: 'T', - developers: ['Square Enix', 'h.a.n.d. Inc.', 'Jupiter Corporation'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 74, - title: "Luigi's Mansion", - platform: '3DS', - date: 1539291600000, - user_score: 8.1, - link: '/game/3ds/luigis-mansion', - esrb_rating: 'E', - developers: ['Nintendo', 'GREZZO'], - genres: ['Action Adventure', 'General'], - }, - { - meta_score: 76, - title: 'Super Mario Party', - platform: 'Switch', - date: 1538686800000, - user_score: 7, - link: '/game/switch/super-mario-party', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 69, - title: 'Dragalia Lost', - platform: 'iOS', - date: 1537995600000, - user_score: 7.7, - link: '/game/ios/dragalia-lost', - esrb_rating: 'T', - developers: ['Cygames'], - genres: ['Role-Playing', 'General'], - }, - { - meta_score: null, - title: 'Yo-kai Watch Blasters: Moon Rabbit Crew', - platform: '3DS', - date: 1537995600000, - user_score: 7.5, - link: '/game/3ds/yo-kai-watch-blasters-moon-rabbit-crew', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Arcade Archives: Excitebike', - platform: 'Switch', - date: 1537477200000, - user_score: null, - link: '/game/switch/arcade-archives-excitebike', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 80, - title: 'Xenoblade Chronicles 2: Torna ~ The Golden Country', - platform: 'Switch', - date: 1536872400000, - user_score: 8.5, - link: '/game/switch/xenoblade-chronicles-2-torna-the-golden-country', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 69, - title: 'Nintendo Labo: Toycon 03 Vehicle Kit', - platform: 'Switch', - date: 1536872400000, - user_score: 7.2, - link: '/game/switch/nintendo-labo-toycon-03-vehicle-kit', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 67, - title: 'Yo-kai Watch Blasters: Red Cat Corps', - platform: '3DS', - date: 1536267600000, - user_score: 6.8, - link: '/game/3ds/yo-kai-watch-blasters-red-cat-corps', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 67, - title: 'Yo-kai Watch Blasters: White Dog Squad', - platform: '3DS', - date: 1536267600000, - user_score: 7.1, - link: '/game/3ds/yo-kai-watch-blasters-white-dog-squad', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 78, - title: 'WarioWare Gold', - platform: '3DS', - date: 1533243600000, - user_score: 8.2, - link: '/game/3ds/warioware-gold', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 62, - title: 'Go Vacation', - platform: 'Switch', - date: 1532638800000, - user_score: 7.7, - link: '/game/switch/go-vacation', - esrb_rating: 'E', - developers: ['Bandai Namco Games'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 2: New Quests Pack 4', - platform: 'Switch', - date: 1532552400000, - user_score: 8.3, - link: '/game/switch/xenoblade-chronicles-2-new-quests-pack-4', - esrb_rating: '', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 82, - title: 'Captain Toad: Treasure Tracker', - platform: 'Switch', - date: 1531429200000, - user_score: 7.9, - link: '/game/switch/captain-toad-treasure-tracker', - esrb_rating: 'E', - developers: ['Nintendo EAD Tokyo ', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', '3D'], - }, - { - meta_score: 79, - title: 'Captain Toad: Treasure Tracker', - platform: '3DS', - date: 1531429200000, - user_score: 7, - link: '/game/3ds/captain-toad-treasure-tracker', - esrb_rating: 'E', - developers: ['Nintendo EAD Tokyo ', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', '3D'], - }, - { - meta_score: 83, - title: 'Octopath Traveler', - platform: 'Switch', - date: 1531342800000, - user_score: 8.4, - link: '/game/switch/octopath-traveler', - esrb_rating: 'T', - developers: ['Square Enix', 'Acquire'], - genres: ['General', 'Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 75, - title: 'Mario Tennis Aces', - platform: 'Switch', - date: 1529614800000, - user_score: 7, - link: '/game/switch/mario-tennis-aces', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Individual', 'Tennis'], - }, - { - meta_score: 82, - title: 'Arcade Archives: Donkey Kong', - platform: 'Switch', - date: 1528923600000, - user_score: 7.7, - link: '/game/switch/arcade-archives-donkey-kong', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 82, - title: 'Splatoon 2: Octo Expansion', - platform: 'Switch', - date: 1528837200000, - user_score: 8.5, - link: '/game/switch/splatoon-2-octo-expansion', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 2: Battle Challenge Mode Pack', - platform: 'Switch', - date: 1528837200000, - user_score: 8.9, - link: '/game/switch/xenoblade-chronicles-2-battle-challenge-mode-pack', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Sushi Striker: The Way of Sushido', - platform: '3DS', - date: 1528405200000, - user_score: 6.6, - link: '/game/3ds/sushi-striker-the-way-of-sushido', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Puzzle', 'Matching'], - }, - { - meta_score: 76, - title: 'Sushi Striker: The Way of Sushido', - platform: 'Switch', - date: 1528405200000, - user_score: 7.7, - link: '/game/switch/sushi-striker-the-way-of-sushido', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Puzzle', 'Matching'], - }, - { - meta_score: 62, - title: 'Pokemon Quest', - platform: 'iOS', - date: 1527627600000, - user_score: 4.1, - link: '/game/ios/pokemon-quest', - esrb_rating: '', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 64, - title: 'Pokemon Quest', - platform: 'Switch', - date: 1527541200000, - user_score: 6, - link: '/game/switch/pokemon-quest', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 2: New Quests Pack 3', - platform: 'Switch', - date: 1527195600000, - user_score: 8.9, - link: '/game/switch/xenoblade-chronicles-2-new-quests-pack-3', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 69, - title: "Dillon's Dead-Heat Breakers", - platform: '3DS', - date: 1527109200000, - user_score: 7.7, - link: '/game/3ds/dillons-dead-heat-breakers', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Vanpool'], - genres: ['Action', 'General'], - }, - { - meta_score: 78, - title: 'Hyrule Warriors: Definitive Edition', - platform: 'Switch', - date: 1526590800000, - user_score: 7.9, - link: '/game/switch/hyrule-warriors-definitive-edition', - esrb_rating: 'T', - developers: ['Koei Tecmo Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 86, - title: 'Donkey Kong Country: Tropical Freeze', - platform: 'Switch', - date: 1525381200000, - user_score: 8.6, - link: '/game/switch/donkey-kong-country-tropical-freeze', - esrb_rating: 'E', - developers: ['Retro Studios'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 77, - title: 'Nintendo Labo: Toycon 01 Variety Kit', - platform: 'Switch', - date: 1524171600000, - user_score: 6.9, - link: '/game/switch/nintendo-labo-toycon-01-variety-kit', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 68, - title: 'Nintendo Labo: Toycon 02 Robot Kit', - platform: 'Switch', - date: 1524171600000, - user_score: 6.5, - link: '/game/switch/nintendo-labo-toycon-02-robot-kit', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Arcade Archives: Punch-Out!', - platform: 'Switch', - date: 1522357200000, - user_score: 7.5, - link: '/game/switch/arcade-archives-punch-out!', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Sports', 'Individual', 'Combat', 'Boxing / Martial Arts'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 2: New Quests Pack 2', - platform: 'Switch', - date: 1522357200000, - user_score: 8.9, - link: '/game/switch/xenoblade-chronicles-2-new-quests-pack-2', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Fire Emblem Warriors: Awakening Pack', - platform: '3DS', - date: 1522270800000, - user_score: null, - link: '/game/3ds/fire-emblem-warriors-awakening-pack', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 71, - title: 'Detective Pikachu', - platform: '3DS', - date: 1521756000000, - user_score: 7.4, - link: '/game/3ds/detective-pikachu', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Adventure', '3D', 'Third-Person'], - }, - { - meta_score: 73, - title: 'Kirby Star Allies', - platform: 'Switch', - date: 1521151200000, - user_score: 7.5, - link: '/game/switch/kirby-star-allies', - esrb_rating: 'E10+', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Kirby Star Allies Demo', - platform: 'Switch', - date: 1520114400000, - user_score: 6.6, - link: '/game/switch/kirby-star-allies-demo', - esrb_rating: '', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 90, - title: 'Bayonetta + Bayonetta 2', - platform: 'Switch', - date: 1518732000000, - user_score: 8.7, - link: '/game/switch/bayonetta-+-bayonetta-2', - esrb_rating: 'M', - developers: ['PlatinumGames'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 92, - title: 'Bayonetta 2', - platform: 'Switch', - date: 1518732000000, - user_score: 8.6, - link: '/game/switch/bayonetta-2', - esrb_rating: 'M', - developers: ['Nintendo', 'PlatinumGames'], - genres: ['Action Adventure', 'Linear'], - }, - { - meta_score: 84, - title: 'Bayonetta', - platform: 'Switch', - date: 1518732000000, - user_score: 8.3, - link: '/game/switch/bayonetta', - esrb_rating: 'M', - developers: ['Nintendo', 'PlatinumGames'], - genres: ['Action Adventure', 'Linear'], - }, - { - meta_score: null, - title: 'Fire Emblem Warriors: Shadow Dragon Pack', - platform: 'Switch', - date: 1518559200000, - user_score: null, - link: '/game/switch/fire-emblem-warriors-shadow-dragon-pack', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Fire Emblem Warriors: Shadow Dragon Pack', - platform: '3DS', - date: 1518559200000, - user_score: null, - link: '/game/3ds/fire-emblem-warriors-shadow-dragon-pack', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 81, - title: 'Dragon Quest Builders', - platform: 'Switch', - date: 1518127200000, - user_score: 8, - link: '/game/switch/dragon-quest-builders', - esrb_rating: 'E10+', - developers: ['Square Enix'], - genres: ['Action Adventure', 'Sandbox'], - }, - { - meta_score: null, - title: 'Pokken Tournament DX: Battle Pack', - platform: 'Switch', - date: 1517349600000, - user_score: 6.6, - link: '/game/switch/pokken-tournament-dx-battle-pack', - esrb_rating: '', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: null, - title: 'Xenoblade Chronicles 2: New Quests Pack 1', - platform: 'Switch', - date: 1517263200000, - user_score: 7.5, - link: '/game/switch/xenoblade-chronicles-2-new-quests-pack-1', - esrb_rating: '', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 57, - title: 'Kirby Battle Royale', - platform: '3DS', - date: 1516312800000, - user_score: 7, - link: '/game/3ds/kirby-battle-royale', - esrb_rating: 'E10+', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 80, - title: 'Style Savvy: Styling Star', - platform: '3DS', - date: 1514152800000, - user_score: 7.6, - link: '/game/3ds/style-savvy-styling-star', - esrb_rating: 'E', - developers: ['Nintendo', 'syn Sophia'], - genres: ['Simulation', 'Virtual', 'Career'], - }, - { - meta_score: null, - title: 'Arcade Archives: Vs. Super Mario Bros.', - platform: 'Switch', - date: 1513893600000, - user_score: 7.2, - link: '/game/switch/arcade-archives-vs-super-mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Fire Emblem Warriors: Fates Pack', - platform: 'Switch', - date: 1513807200000, - user_score: 7.6, - link: '/game/switch/fire-emblem-warriors-fates-pack', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Fire Emblem Warriors: Fates Pack', - platform: '3DS', - date: 1513807200000, - user_score: 9.1, - link: '/game/3ds/fire-emblem-warriors-fates-pack', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 81, - title: "The Legend of Zelda: Breath of the Wild - The Champions'Ballad", - platform: 'Switch', - date: 1512597600000, - user_score: 8.5, - link: '/game/switch/the-legend-of-zelda-breath-of-the-wild---the-champions-ballad', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: null, - title: "The Legend of Zelda: Breath of the Wild - The Champions'Ballad", - platform: 'WIIU', - date: 1512597600000, - user_score: 9, - link: '/game/wii-u/the-legend-of-zelda-breath-of-the-wild---the-champions-ballad', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 83, - title: 'Xenoblade Chronicles 2', - platform: 'Switch', - date: 1512079200000, - user_score: 8.5, - link: '/game/switch/xenoblade-chronicles-2', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 72, - title: 'Animal Crossing: Pocket Camp', - platform: 'iOS', - date: 1511215200000, - user_score: 6.8, - link: '/game/ios/animal-crossing-pocket-camp', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 84, - title: 'Pokemon Ultra Sun', - platform: '3DS', - date: 1510869600000, - user_score: 7.7, - link: '/game/3ds/pokemon-ultra-sun', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 84, - title: 'Pokemon Ultra Moon', - platform: '3DS', - date: 1510869600000, - user_score: 7.6, - link: '/game/3ds/pokemon-ultra-moon', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: "Pokemon Ultra Sun & Pokemon Ultra Moon Veteran Trainer's Dual Pack", - platform: '3DS', - date: 1510869600000, - user_score: 6.3, - link: '/game/3ds/pokemon-ultra-sun-pokemon-ultra-moon-veteran-trainers-dual-pack', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 77, - title: 'Ittle Dew 2+', - platform: 'Switch', - date: 1510610400000, - user_score: 7.8, - link: '/game/switch/ittle-dew-2+', - esrb_rating: 'E10+', - developers: ['Ludosity Interactive'], - genres: ['Role-Playing', 'Action Adventure', 'General', 'Action RPG'], - }, - { - meta_score: 59, - title: 'Mario Party: The Top 100', - platform: '3DS', - date: 1510264800000, - user_score: 6.2, - link: '/game/3ds/mario-party-the-top-100', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 84, - title: 'Snipperclips Plus: Cut It Out, Together!', - platform: 'Switch', - date: 1510264800000, - user_score: 8, - link: '/game/switch/snipperclips-plus-cut-it-out-together!', - esrb_rating: 'E', - developers: ['SFB Games'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: 97, - title: 'Super Mario Odyssey', - platform: 'Switch', - date: 1509051600000, - user_score: 8.9, - link: '/game/switch/super-mario-odyssey', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 69, - title: 'Fire Emblem Warriors', - platform: '3DS', - date: 1508446800000, - user_score: 7.8, - link: '/game/3ds/fire-emblem-warriors', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 74, - title: 'Fire Emblem Warriors', - platform: 'Switch', - date: 1508446800000, - user_score: 7.7, - link: '/game/switch/fire-emblem-warriors', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 72, - title: "Layton's Mystery Journey: Katrielle and The Millionaires'Conspiracy", - platform: '3DS', - date: 1507237200000, - user_score: 6.3, - link: '/game/3ds/laytons-mystery-journey-katrielle-and-the-millionaires-conspiracy', - esrb_rating: 'E10+', - developers: ['Level 5', 'h.a.n.d. Inc.'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: 81, - title: "Mario & Luigi: Superstar Saga + Bowser's Minions", - platform: '3DS', - date: 1507237200000, - user_score: 8.2, - link: '/game/3ds/mario-luigi-superstar-saga-+-bowsers-minions', - esrb_rating: 'E', - developers: ['Alphadream Corporation'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 73, - title: 'Yo-kai Watch 2: Psychic Specters', - platform: '3DS', - date: 1506632400000, - user_score: 8.5, - link: '/game/3ds/yo-kai-watch-2-psychic-specters', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Hive Jump', - platform: 'WIIU', - date: 1506546000000, - user_score: null, - link: '/game/wii-u/hive-jump', - esrb_rating: 'E10+', - developers: ['Graphite Lab'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Monster Hunter Stories: The Legend of Zelda', - platform: '3DS', - date: 1506546000000, - user_score: null, - link: '/game/3ds/monster-hunter-stories-the-legend-of-zelda', - esrb_rating: 'E10+', - developers: ['Capcom'], - genres: ['Role-Playing', 'Action RPG', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Arcade Archives: Mario Bros.', - platform: 'Switch', - date: 1506459600000, - user_score: 6.7, - link: '/game/switch/arcade-archives-mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 75, - title: 'Dragon Ball: Xenoverse 2', - platform: 'Switch', - date: 1506027600000, - user_score: 7.5, - link: '/game/switch/dragon-ball-xenoverse-2', - esrb_rating: 'T', - developers: ['Dimps Corporation'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 79, - title: 'Pokken Tournament DX', - platform: 'Switch', - date: 1506027600000, - user_score: 7.3, - link: '/game/switch/pokken-tournament-dx', - esrb_rating: 'E10+', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 85, - title: 'Metroid: Samus Returns', - platform: '3DS', - date: 1505422800000, - user_score: 8.7, - link: '/game/3ds/metroid-samus-returns', - esrb_rating: 'E10+', - developers: ['Mercury Steam'], - genres: ['Action', 'Action Adventure', 'Platformer', 'Open-World', '', 'Metroidvania'], - }, - { - meta_score: null, - title: 'ARMS: Lola Pop', - platform: 'Switch', - date: 1505250000000, - user_score: null, - link: '/game/switch/arms-lola-pop', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 79, - title: 'Monster Hunter Stories', - platform: '3DS', - date: 1504818000000, - user_score: 8.2, - link: '/game/3ds/monster-hunter-stories', - esrb_rating: 'E10+', - developers: ['Capcom'], - genres: ['Role-Playing', 'Action RPG', 'Japanese-Style'], - }, - { - meta_score: 70, - title: 'Sine Mora EX', - platform: 'Switch', - date: 1502139600000, - user_score: 7.2, - link: '/game/switch/sine-mora-ex', - esrb_rating: 'M', - developers: ['Grasshopper Manufacture'], - genres: ['Action', 'Shooter', "Shoot-'Em-Up", 'Horizontal'], - }, - { - meta_score: 69, - title: 'Hey! Pikmin', - platform: '3DS', - date: 1501189200000, - user_score: 6.6, - link: '/game/3ds/hey!-pikmin', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Arzest'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 67, - title: 'Miitopia', - platform: '3DS', - date: 1501189200000, - user_score: 7.9, - link: '/game/3ds/miitopia', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Role-Playing', 'General'], - }, - { - meta_score: 83, - title: 'Splatoon 2', - platform: 'Switch', - date: 1500584400000, - user_score: 8.4, - link: '/game/switch/splatoon-2', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: 73, - title: "Layton's Mystery Journey: Katrielle and The Millionaire's Conspiracy", - platform: 'iOS', - date: 1500498000000, - user_score: 7.3, - link: '/game/ios/laytons-mystery-journey-katrielle-and-the-millionaires-conspiracy', - esrb_rating: '', - developers: ['Level 5', 'h.a.n.d. Inc.'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Miitopia: Casting Call', - platform: '3DS', - date: 1499893200000, - user_score: 7.1, - link: '/game/3ds/miitopia-casting-call', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: null, - title: 'ARMS: Max Brass', - platform: 'Switch', - date: 1499806800000, - user_score: 7.3, - link: '/game/switch/arms-max-brass', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 53, - title: 'Flip Wars', - platform: 'Switch', - date: 1499288400000, - user_score: 5.9, - link: '/game/switch/flip-wars', - esrb_rating: 'T', - developers: ['OVER FENCE CO.', 'LTD.', 'Over Fence'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: 69, - title: "Kirby's Blowout Blast", - platform: '3DS', - date: 1499288400000, - user_score: 7, - link: '/game/3ds/kirbys-blowout-blast', - esrb_rating: 'E', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Action', 'General'], - }, - { - meta_score: 78, - title: 'The Legend of Zelda: Breath of the Wild - The Master Trials', - platform: 'Switch', - date: 1498770000000, - user_score: 7.7, - link: '/game/switch/the-legend-of-zelda-breath-of-the-wild---the-master-trials', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: null, - title: 'The Legend of Zelda: Breath of the Wild - The Master Trials', - platform: 'WIIU', - date: 1498770000000, - user_score: 8.6, - link: '/game/wii-u/the-legend-of-zelda-breath-of-the-wild---the-master-trials', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 76, - title: 'Ever Oasis', - platform: '3DS', - date: 1498165200000, - user_score: 8.1, - link: '/game/3ds/ever-oasis', - esrb_rating: 'E10+', - developers: ['GREZZO'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Cipher Legends I', - platform: '3DS', - date: 1498078800000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---cipher-legends-i', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Cipher Legends II', - platform: '3DS', - date: 1498078800000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---cipher-legends-ii', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Cipher Companions Pack', - platform: '3DS', - date: 1498078800000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---cipher-companions-pack', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 77, - title: 'ARMS', - platform: 'Switch', - date: 1497560400000, - user_score: 7.1, - link: '/game/switch/arms', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: [ - 'Action', - 'Sports', - 'Fighting', - 'Individual', - '3D', - 'Combat', - 'Boxing / Martial Arts', - ], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Rise of the Deliverance Pack', - platform: '3DS', - date: 1496264400000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---rise-of-the-deliverance-pack', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Flight from the Ruins', - platform: '3DS', - date: 1496264400000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---flight-from-the-ruins', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Outpost Rescue', - platform: '3DS', - date: 1496264400000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---outpost-rescue', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Battle of Zofia Harbor', - platform: '3DS', - date: 1496264400000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---battle-of-zofia-harbor', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Siege of Zofia Castle', - platform: '3DS', - date: 1496264400000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---siege-of-zofia-castle', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'ARMS: Global Testpunch', - platform: 'Switch', - date: 1495746000000, - user_score: null, - link: '/game/switch/arms-global-testpunch', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Undaunted Heroes Pack', - platform: '3DS', - date: 1495659600000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---undaunted-heroes-pack', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Inner Sanctum', - platform: '3DS', - date: 1495659600000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---inner-sanctum', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Lords of the Grave', - platform: '3DS', - date: 1495659600000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---lords-of-the-grave', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Lost Altars Pack', - platform: '3DS', - date: 1495659600000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---lost-altars-pack', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Wealth Before Health', - platform: '3DS', - date: 1495659600000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---wealth-before-health', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 81, - title: 'Fire Emblem Echoes: Shadows of Valentia', - platform: '3DS', - date: 1495141200000, - user_score: 8.6, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Fledging Warriors Pack', - platform: '3DS', - date: 1495141200000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---fledging-warriors-pack', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - The Astral Temple', - platform: '3DS', - date: 1495141200000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---the-astral-temple', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Wretches and Riches', - platform: '3DS', - date: 1495141200000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---wretches-and-riches', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem Echoes: Shadows of Valentia - Band of Bandages', - platform: '3DS', - date: 1495141200000, - user_score: null, - link: '/game/3ds/fire-emblem-echoes-shadows-of-valentia---band-of-bandages', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 92, - title: 'Mario Kart 8 Deluxe', - platform: 'Switch', - date: 1493326800000, - user_score: 8.6, - link: '/game/switch/mario-kart-8-deluxe', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Other', 'Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 83, - title: 'BYE-BYE BOXBOY!', - platform: '3DS', - date: 1491944400000, - user_score: 7.9, - link: '/game/3ds/bye-bye-boxboy!', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: 57, - title: 'Team Kirby Clash Deluxe', - platform: '3DS', - date: 1491944400000, - user_score: 6.5, - link: '/game/3ds/team-kirby-clash-deluxe', - esrb_rating: 'E', - developers: ['Nintendo', 'HAL Labs'], - genres: ['Action', 'Miscellaneous', 'General', 'Party / Minigame'], - }, - { - meta_score: 62, - title: 'Mario Sports Superstars', - platform: '3DS', - date: 1490306400000, - user_score: 7.3, - link: '/game/3ds/mario-sports-superstars', - esrb_rating: 'E', - developers: ['Nintendo', 'Camelot Software Planning'], - genres: ['Sports', 'General'], - }, - { - meta_score: null, - title: 'Splatoon 2: Global Testfire', - platform: 'Switch', - date: 1490306400000, - user_score: null, - link: '/game/switch/splatoon-2-global-testfire', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: 96, - title: 'The Legend of Zelda: Breath of the Wild', - platform: 'WIIU', - date: 1488492000000, - user_score: 8.3, - link: '/game/wii-u/the-legend-of-zelda-breath-of-the-wild', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Fantasy', 'Fantasy', 'Action Adventure', 'Open-World'], - }, - { - meta_score: 97, - title: 'The Legend of Zelda: Breath of the Wild', - platform: 'Switch', - date: 1488492000000, - user_score: 8.7, - link: '/game/switch/the-legend-of-zelda-breath-of-the-wild', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 58, - title: '1-2-Switch', - platform: 'Switch', - date: 1488492000000, - user_score: 4.8, - link: '/game/switch/1-2-switch', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 80, - title: 'Snipperclips - Cut it out, together!', - platform: 'Switch', - date: 1488492000000, - user_score: 8.2, - link: '/game/switch/snipperclips---cut-it-out-together!', - esrb_rating: 'E', - developers: ['Nintendo', 'SFB Games'], - genres: ['Puzzle', 'General'], - }, - { - meta_score: 64, - title: 'Tank Troopers', - platform: '3DS', - date: 1487196000000, - user_score: 6, - link: '/game/3ds/tank-troopers', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Vehicle', 'Combat'], - }, - { - meta_score: 77, - title: "Poochy & Yoshi's Woolly World", - platform: '3DS', - date: 1486072800000, - user_score: 7.8, - link: '/game/3ds/poochy-yoshis-woolly-world', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 72, - title: 'Fire Emblem Heroes', - platform: 'iOS', - date: 1485986400000, - user_score: 7.2, - link: '/game/ios/fire-emblem-heroes', - esrb_rating: 'T', - developers: ['Nintendo', 'Intelligent Systems'], - genres: ['Role-Playing', 'Strategy', 'Turn-Based', 'General', 'Tactics'], - }, - { - meta_score: 85, - title: 'Dragon Quest VIII: Journey of the Cursed King', - platform: '3DS', - date: 1484863200000, - user_score: 8.6, - link: '/game/3ds/dragon-quest-viii-journey-of-the-cursed-king', - esrb_rating: 'T', - developers: ['TOSE', 'Cygames'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 76, - title: 'Super Mario Run', - platform: 'iOS', - date: 1481752800000, - user_score: 6.2, - link: '/game/ios/super-mario-run', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Excitebots: Trick Racing', - platform: 'WIIU', - date: 1481752800000, - user_score: null, - link: '/game/wii-u/excitebots-trick-racing', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: null, - title: 'Animal Crossing: New Leaf - Welcome Amiibo', - platform: '3DS', - date: 1480888800000, - user_score: 7.6, - link: '/game/3ds/animal-crossing-new-leaf---welcome-amiibo', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 73, - title: 'Super Mario Maker for Nintendo 3DS', - platform: '3DS', - date: 1480629600000, - user_score: 6.5, - link: '/game/3ds/super-mario-maker-for-nintendo-3ds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 87, - title: 'Pokemon Sun', - platform: '3DS', - date: 1479420000000, - user_score: 7.6, - link: '/game/3ds/pokemon-sun', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 87, - title: 'Pokemon Moon', - platform: '3DS', - date: 1479420000000, - user_score: 7.6, - link: '/game/3ds/pokemon-moon', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Pokemon Sun and Moon Dual Pack', - platform: '3DS', - date: 1479420000000, - user_score: 6.1, - link: '/game/3ds/pokemon-sun-and-moon-dual-pack', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Swapdoodle', - platform: '3DS', - date: 1479333600000, - user_score: null, - link: '/game/3ds/swapdoodle', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: 68, - title: 'Mario Party: Star Rush', - platform: '3DS', - date: 1478210400000, - user_score: 6.9, - link: '/game/3ds/mario-party-star-rush', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Hyrule Warriors Legends: A Link Between Worlds Pack', - platform: '3DS', - date: 1477864800000, - user_score: null, - link: '/game/3ds/hyrule-warriors-legends-a-link-between-worlds-pack', - esrb_rating: '', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Pokemon Sun and Pokemon Moon Special Demo Version', - platform: '3DS', - date: 1476738000000, - user_score: 5.9, - link: '/game/3ds/pokemon-sun-and-pokemon-moon-special-demo-version', - esrb_rating: '', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 73, - title: 'Disney Magical World 2', - platform: '3DS', - date: 1476392400000, - user_score: 5.5, - link: '/game/3ds/disney-magical-world-2', - esrb_rating: 'E', - developers: ['h.a.n.d. Inc.', 'Bandai Namco Games'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 76, - title: 'Paper Mario: Color Splash', - platform: 'WIIU', - date: 1475787600000, - user_score: 7.1, - link: '/game/wii-u/paper-mario-color-splash', - esrb_rating: 'E', - developers: ['Nintendo', 'Intelligent Systems'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 72, - title: 'Yo-kai Watch 2: Bony Spirits', - platform: '3DS', - date: 1475182800000, - user_score: 8, - link: '/game/3ds/yo-kai-watch-2-bony-spirits', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 70, - title: 'Yo-kai Watch 2: Fleshy Souls', - platform: '3DS', - date: 1475182800000, - user_score: 8, - link: '/game/3ds/yo-kai-watch-2-fleshy-souls', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: 81, - title: 'Dragon Quest VII: Fragments of the Forgotten Past', - platform: '3DS', - date: 1473973200000, - user_score: 8.2, - link: '/game/3ds/dragon-quest-vii-fragments-of-the-forgotten-past', - esrb_rating: 'E10+', - developers: ['ArtePiazza'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 86, - title: 'Picross 3D: Round 2', - platform: '3DS', - date: 1472677200000, - user_score: 7.8, - link: '/game/3ds/picross-3d-round-2', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Puzzle', 'Logic'], - }, - { - meta_score: null, - title: 'Hyrule Warriors Legends: Phantom Hourglass & Spirit Tracks Pack', - platform: '3DS', - date: 1472677200000, - user_score: null, - link: '/game/3ds/hyrule-warriors-legends-phantom-hourglass-spirit-tracks-pack', - esrb_rating: 'E10+', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 64, - title: 'Metroid Prime: Federation Force', - platform: '3DS', - date: 1471554000000, - user_score: 5.4, - link: '/game/3ds/metroid-prime-federation-force', - esrb_rating: 'T', - developers: ['Next Level Games', 'Nintendo'], - genres: ['Action', 'Shooter', 'First-Person', 'Arcade'], - }, - { - meta_score: 78, - title: 'Style Savvy: Fashion Forward', - platform: '3DS', - date: 1471554000000, - user_score: 6.9, - link: '/game/3ds/style-savvy-fashion-forward', - esrb_rating: 'E', - developers: ['syn Sophia'], - genres: ['Simulation', 'Virtual', 'Career'], - }, - { - meta_score: null, - title: 'Metroid Prime: Blast Ball', - platform: '3DS', - date: 1469048400000, - user_score: 7.1, - link: '/game/3ds/metroid-prime-blast-ball', - esrb_rating: '', - developers: ['Next Level Games'], - genres: ['Action', 'Shooter', 'First-Person', 'Arcade'], - }, - { - meta_score: 69, - title: 'Pokemon GO', - platform: 'iOS', - date: 1467752400000, - user_score: 5.5, - link: '/game/ios/pokemon-go', - esrb_rating: '', - developers: ['Niantic Labs'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Teddy Together', - platform: '3DS', - date: 1467320400000, - user_score: null, - link: '/game/3ds/teddy-together', - esrb_rating: '', - developers: ['Arika'], - genres: ['Action', 'General'], - }, - { - meta_score: 80, - title: 'BoxBoxBoy!', - platform: '3DS', - date: 1467234000000, - user_score: 7.9, - link: '/game/3ds/boxboxboy!', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: null, - title: "Hyrule Warriors Legends: Link's Awakening Pack", - platform: '3DS', - date: 1467234000000, - user_score: null, - link: '/game/3ds/hyrule-warriors-legends-links-awakening-pack', - esrb_rating: '', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 80, - title: 'Tokyo Mirage Sessions #FE', - platform: 'WIIU', - date: 1466715600000, - user_score: 7.9, - link: '/game/wii-u/tokyo-mirage-sessions-fe', - esrb_rating: 'T', - developers: ['Atlus'], - genres: [ - 'General', - 'Fantasy', - 'Role-Playing', - 'Strategy', - 'Turn-Based', - 'Japanese-Style', - 'General', - ], - }, - { - meta_score: 65, - title: 'Mario & Sonic at the Rio 2016 Olympic Games', - platform: 'WIIU', - date: 1466715600000, - user_score: 7.7, - link: '/game/wii-u/mario-sonic-at-the-rio-2016-olympic-games', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Sega Sports R&D'], - genres: ['Sports', 'Individual', 'Athletics'], - }, - { - meta_score: null, - title: 'Tokyo Mirage Sessions #FE - EXPedition Hunter', - platform: 'WIIU', - date: 1466715600000, - user_score: null, - link: '/game/wii-u/tokyo-mirage-sessions-fe---expedition-hunter', - esrb_rating: 'T', - developers: ['Atlus'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Tokyo Mirage Sessions #FE - Masterful Hunter', - platform: 'WIIU', - date: 1466715600000, - user_score: null, - link: '/game/wii-u/tokyo-mirage-sessions-fe---masterful-hunter', - esrb_rating: 'T', - developers: ['Atlus'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Tokyo Mirage Sessions #FE - Savage Hunter', - platform: 'WIIU', - date: 1466715600000, - user_score: null, - link: '/game/wii-u/tokyo-mirage-sessions-fe---savage-hunter', - esrb_rating: 'T', - developers: ['Atlus'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Tokyo Mirage Sessions #FE - Tokyo Millennium Collection', - platform: 'WIIU', - date: 1466715600000, - user_score: null, - link: '/game/wii-u/tokyo-mirage-sessions-fe---tokyo-millennium-collection', - esrb_rating: 'T', - developers: ['Atlus'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 83, - title: 'Rhythm Heaven Megamix', - platform: '3DS', - date: 1465938000000, - user_score: 8.2, - link: '/game/3ds/rhythm-heaven-megamix', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Rhythm', 'Music'], - }, - { - meta_score: 81, - title: 'Kirby: Planet Robobot', - platform: '3DS', - date: 1465506000000, - user_score: 8.7, - link: '/game/3ds/kirby-planet-robobot', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Team Kirby Clash', - platform: '3DS', - date: 1465506000000, - user_score: 6.5, - link: '/game/3ds/team-kirby-clash', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'Hyrule Warriors Legends: Master Wind Waker Pack', - platform: '3DS', - date: 1463605200000, - user_score: null, - link: '/game/3ds/hyrule-warriors-legends-master-wind-waker-pack', - esrb_rating: '', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 72, - title: 'Disney Art Academy', - platform: '3DS', - date: 1463086800000, - user_score: 7.1, - link: '/game/3ds/disney-art-academy', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Application'], - }, - { - meta_score: 83, - title: 'Pocket Card Jockey', - platform: '3DS', - date: 1462395600000, - user_score: 8.1, - link: '/game/3ds/pocket-card-jockey', - esrb_rating: 'E10+', - developers: ['Game Freak'], - genres: ['Miscellaneous', 'Board / Card Game'], - }, - { - meta_score: 69, - title: 'Star Fox Zero', - platform: 'WIIU', - date: 1461272400000, - user_score: 7.4, - link: '/game/wii-u/star-fox-zero', - esrb_rating: 'E10+', - developers: ['PlatinumGames'], - genres: [ - 'Action', - 'Third-Person', - 'Shooter', - 'Modern', - 'Rail', - 'Simulation', - 'Space', - 'Combat', - ], - }, - { - meta_score: 74, - title: 'Star Fox Guard', - platform: 'WIIU', - date: 1461272400000, - user_score: 7.4, - link: '/game/wii-u/star-fox-guard', - esrb_rating: 'E10+', - developers: ['Nintendo', 'PlatinumGames'], - genres: ['Action', 'First-Person', 'Sci-Fi', 'Shooter', 'Strategy', 'Real-Time', 'Defense'], - }, - { - meta_score: null, - title: 'Star Fox Zero Double Pack', - platform: 'WIIU', - date: 1461272400000, - user_score: 8, - link: '/game/wii-u/star-fox-zero-double-pack', - esrb_rating: 'E10+', - developers: ['Nintendo', 'PlatinumGames'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 81, - title: 'Bravely Second: End Layer', - platform: '3DS', - date: 1460667600000, - user_score: 8.2, - link: '/game/3ds/bravely-second-end-layer', - esrb_rating: 'T', - developers: ['Silicon Studio'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 72, - title: 'Miitomo', - platform: 'iOS', - date: 1459371600000, - user_score: 7, - link: '/game/ios/miitomo', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Virtual Life'], - }, - { - meta_score: null, - title: 'My Nintendo Picross - The Legend of Zelda: Twilight Princess', - platform: '3DS', - date: 1459285200000, - user_score: 7.9, - link: '/game/3ds/my-nintendo-picross---the-legend-of-zelda-twilight-princess', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Puzzle', 'Logic'], - }, - { - meta_score: 70, - title: 'Hyrule Warriors Legends', - platform: '3DS', - date: 1458856800000, - user_score: 7.5, - link: '/game/3ds/hyrule-warriors-legends', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Mini-Mario & Friends: amiibo Challenge', - platform: 'WIIU', - date: 1458856800000, - user_score: 6.9, - link: '/game/wii-u/mini-mario-friends-amiibo-challenge', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: null, - title: 'Mini-Mario & Friends: amiibo Challenge', - platform: '3DS', - date: 1458856800000, - user_score: 6.8, - link: '/game/3ds/mini-mario-friends-amiibo-challenge', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: 60, - title: 'Mario & Sonic at the Rio 2016 Olympic Games', - platform: '3DS', - date: 1458252000000, - user_score: 6.9, - link: '/game/3ds/mario-sonic-at-the-rio-2016-olympic-games', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Sega Sports R&D'], - genres: ['Sports', 'Individual', 'Athletics'], - }, - { - meta_score: 76, - title: 'Pokken Tournament', - platform: 'WIIU', - date: 1458252000000, - user_score: 7.4, - link: '/game/wii-u/pokken-tournament', - esrb_rating: 'E10+', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 88, - title: 'Fire Emblem Fates: Revelation', - platform: '3DS', - date: 1457560800000, - user_score: 7.2, - link: '/game/3ds/fire-emblem-fates-revelation', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 86, - title: 'The Legend of Zelda: Twilight Princess HD', - platform: 'WIIU', - date: 1457042400000, - user_score: 8.6, - link: '/game/wii-u/the-legend-of-zelda-twilight-princess-hd', - esrb_rating: 'T', - developers: ['Tantalus', 'Tantatus', 'Nintendo'], - genres: ['Action Adventure', 'General', 'Open-World'], - }, - { - meta_score: 87, - title: 'Fire Emblem Fates: Conquest', - platform: '3DS', - date: 1455832800000, - user_score: 8, - link: '/game/3ds/fire-emblem-fates-conquest', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Fantasy', 'Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 86, - title: 'Fire Emblem Fates: Birthright', - platform: '3DS', - date: 1455832800000, - user_score: 7.8, - link: '/game/3ds/fire-emblem-fates-birthright', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 88, - title: 'Fire Emblem Fates: Special Edition', - platform: '3DS', - date: 1455832800000, - user_score: 7.8, - link: '/game/3ds/fire-emblem-fates-special-edition', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: 76, - title: 'Mario & Luigi: Paper Jam', - platform: '3DS', - date: 1453413600000, - user_score: 7.3, - link: '/game/3ds/mario-luigi-paper-jam', - esrb_rating: 'E', - developers: ['Nintendo', 'Alphadream Corporation'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: 84, - title: 'Xenoblade Chronicles X', - platform: 'WIIU', - date: 1449180000000, - user_score: 9.1, - link: '/game/wii-u/xenoblade-chronicles-x', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Action RPG', 'Role-Playing', 'Action RPG'], - }, - { - meta_score: 75, - title: 'Pokemon Picross', - platform: '3DS', - date: 1449093600000, - user_score: 7.5, - link: '/game/3ds/pokemon-picross', - esrb_rating: 'E', - developers: ['Nintendo', 'Jupiter Corporation'], - genres: ['Miscellaneous', 'General', 'Puzzle', 'Logic'], - }, - { - meta_score: 69, - title: 'Pokemon Super Mystery Dungeon', - platform: '3DS', - date: 1447970400000, - user_score: 8.2, - link: '/game/3ds/pokemon-super-mystery-dungeon', - esrb_rating: 'E', - developers: ['Spike Chunsoft Co. Ltd.', 'Spike Chunsoft'], - genres: ['Role-Playing', 'Roguelike'], - }, - { - meta_score: 58, - title: 'Mario Tennis: Ultra Smash', - platform: 'WIIU', - date: 1447970400000, - user_score: 5.1, - link: '/game/wii-u/mario-tennis-ultra-smash', - esrb_rating: 'E', - developers: ['Nintendo', 'Camelot Software Planning'], - genres: ['Sports', 'Individual', 'Tennis'], - }, - { - meta_score: 46, - title: 'Animal Crossing: amiibo Festival', - platform: 'WIIU', - date: 1447365600000, - user_score: 4, - link: '/game/wii-u/animal-crossing-amiibo-festival', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Miscellaneous', 'Board / Card Game'], - }, - { - meta_score: 56, - title: 'Nintendo Badge Arcade', - platform: '3DS', - date: 1447106400000, - user_score: 4, - link: '/game/3ds/nintendo-badge-arcade', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 76, - title: 'Yo-kai Watch', - platform: '3DS', - date: 1446760800000, - user_score: 8.1, - link: '/game/3ds/yo-kai-watch', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Japanese-Style', 'Role-Playing', 'Trainer'], - }, - { - meta_score: 73, - title: 'The Legend of Zelda: Tri Force Heroes', - platform: '3DS', - date: 1445547600000, - user_score: 7.2, - link: '/game/3ds/the-legend-of-zelda-tri-force-heroes', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Open-World'], - }, - { - meta_score: 67, - title: 'Fatal Frame: Maiden of Black Water', - platform: 'WIIU', - date: 1445461200000, - user_score: 8, - link: '/game/wii-u/fatal-frame-maiden-of-black-water', - esrb_rating: 'M', - developers: ['Koei Tecmo Games'], - genres: ['Action', 'General', 'Horror', 'Action Adventure', 'Survival'], - }, - { - meta_score: 78, - title: "Yoshi's Woolly World", - platform: 'WIIU', - date: 1444942800000, - user_score: 8.4, - link: '/game/wii-u/yoshis-woolly-world', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Action Adventure', 'Platformer', '2D', 'Fantasy', 'Action', 'Platformer', '2D'], - }, - { - meta_score: 59, - title: 'Chibi-Robo! Zip Lash', - platform: '3DS', - date: 1444338000000, - user_score: 5.1, - link: '/game/3ds/chibi-robo!-zip-lash', - esrb_rating: 'E', - developers: ['Nintendo', 'Skip Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 66, - title: 'Animal Crossing: Happy Home Designer', - platform: '3DS', - date: 1443128400000, - user_score: 6.9, - link: '/game/3ds/animal-crossing-happy-home-designer', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Virtual', 'Career'], - }, - { - meta_score: 88, - title: 'Super Mario Maker', - platform: 'WIIU', - date: 1441918800000, - user_score: 8.7, - link: '/game/wii-u/super-mario-maker', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 62, - title: 'Pokemon Shuffle Mobile', - platform: 'iOS', - date: 1440968400000, - user_score: 6.4, - link: '/game/ios/pokemon-shuffle-mobile', - esrb_rating: '', - developers: ['Genius Sonority Inc.'], - genres: ['Puzzle', 'Matching'], - }, - { - meta_score: 43, - title: "Devil's Third", - platform: 'WIIU', - date: 1440709200000, - user_score: 6.6, - link: '/game/wii-u/devils-third', - esrb_rating: 'M', - developers: ['Valhalla Game Studios'], - genres: [ - 'Action Adventure', - 'General', - 'Modern', - 'Action', - 'Shooter', - 'Third-Person', - 'Arcade', - ], - }, - { - meta_score: 73, - title: 'LBX: Little Battlers eXperience', - platform: '3DS', - date: 1440104400000, - user_score: 7.4, - link: '/game/3ds/lbx-little-battlers-experience', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Action', 'Role-Playing', 'General', 'Action RPG'], - }, - { - meta_score: 82, - title: 'Art Academy: Home Studio', - platform: 'WIIU', - date: 1435179600000, - user_score: 7.9, - link: '/game/wii-u/art-academy-home-studio', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment'], - }, - { - meta_score: null, - title: 'Earthbound Beginnings', - platform: 'WIIU', - date: 1434229200000, - user_score: 8.2, - link: '/game/wii-u/earthbound-beginnings', - esrb_rating: '', - developers: ['Pax Softonica'], - genres: ['Role-Playing', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Smash Controller', - platform: '3DS', - date: 1434229200000, - user_score: null, - link: '/game/3ds/smash-controller', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: 69, - title: 'Dr. Mario: Miracle Cure', - platform: '3DS', - date: 1433970000000, - user_score: 6.9, - link: '/game/3ds/dr-mario-miracle-cure', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Puzzle', 'Stacking'], - }, - { - meta_score: 81, - title: 'Splatoon', - platform: 'WIIU', - date: 1432846800000, - user_score: 8.7, - link: '/game/wii-u/splatoon', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Fantasy', 'Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: 73, - title: 'Puzzle & Dragons Z + Puzzle & Dragons: Super Mario Bros. Edition', - platform: '3DS', - date: 1432242000000, - user_score: 7.6, - link: '/game/3ds/puzzle-dragons-z-+-puzzle-dragons-super-mario-bros-edition', - esrb_rating: 'E', - developers: ['GungHo'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 83, - title: 'Stretchmo', - platform: '3DS', - date: 1431550800000, - user_score: 8, - link: '/game/3ds/stretchmo', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: null, - title: "amiibo Tap: Nintendo's Greatest Bits", - platform: 'WIIU', - date: 1430341200000, - user_score: 7.6, - link: '/game/wii-u/amiibo-tap-nintendos-greatest-bits', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: null, - title: 'Super Smash Bros. for Nintendo 3DS / Wii U: Mewtwo', - platform: '3DS', - date: 1430168400000, - user_score: null, - link: '/game/3ds/super-smash-bros-for-nintendo-3ds-wii-u-mewtwo', - esrb_rating: '', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'Super Smash Bros. for Nintendo 3DS / Wii U: Mewtwo', - platform: 'WIIU', - date: 1430168400000, - user_score: null, - link: '/game/wii-u/super-smash-bros-for-nintendo-3ds-wii-u-mewtwo', - esrb_rating: '', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: 90, - title: 'Mario Kart 8 DLC Pack 2', - platform: 'WIIU', - date: 1429736400000, - user_score: 8.2, - link: '/game/wii-u/mario-kart-8-dlc-pack-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Kart', 'Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: 86, - title: 'Xenoblade Chronicles 3D', - platform: '3DS', - date: 1428613200000, - user_score: 8.7, - link: '/game/3ds/xenoblade-chronicles-3d', - esrb_rating: 'T', - developers: ['Monster Games Inc.'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 58, - title: 'Pokemon Rumble World', - platform: '3DS', - date: 1428440400000, - user_score: 6.2, - link: '/game/3ds/pokemon-rumble-world', - esrb_rating: 'E10+', - developers: ['Ambrella', 'The Pokemon Company'], - genres: ['Action', 'General', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 80, - title: 'BOXBOY!', - platform: '3DS', - date: 1427922000000, - user_score: 8.1, - link: '/game/3ds/boxboy!', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Puzzle', 'Action'], - }, - { - meta_score: 66, - title: 'Mario Party 10', - platform: 'WIIU', - date: 1426802400000, - user_score: 6.4, - link: '/game/wii-u/mario-party-10', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Party', 'Miscellaneous', 'Party / Minigame'], - }, - { - meta_score: 57, - title: 'Fossil Fighters: Frontier', - platform: '3DS', - date: 1426802400000, - user_score: 5.3, - link: '/game/3ds/fossil-fighters-frontier', - esrb_rating: 'E10+', - developers: ['RED Entertainment', 'Spike Chunsoft'], - genres: ['Role-Playing', 'General', 'Trainer'], - }, - { - meta_score: 69, - title: 'Code Name: S.T.E.A.M.', - platform: '3DS', - date: 1426197600000, - user_score: 7.8, - link: '/game/3ds/code-name-steam', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Sci-Fi', 'Strategy', 'Turn-Based', 'Tactics'], - }, - { - meta_score: null, - title: 'Hyrule Warriors: Boss Pack', - platform: 'WIIU', - date: 1426111200000, - user_score: 7.6, - link: '/game/wii-u/hyrule-warriors-boss-pack', - esrb_rating: '', - developers: ['Tecmo Koei Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 70, - title: 'Mario vs. Donkey Kong: Tipping Stars', - platform: 'WIIU', - date: 1425506400000, - user_score: 7.5, - link: '/game/wii-u/mario-vs-donkey-kong-tipping-stars', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', '2D'], - }, - { - meta_score: 70, - title: 'Mario vs. Donkey Kong: Tipping Stars', - platform: '3DS', - date: 1425506400000, - user_score: 7.4, - link: '/game/3ds/mario-vs-donkey-kong-tipping-stars', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', '2D'], - }, - { - meta_score: 73, - title: 'Kirby and the Rainbow Curse', - platform: 'WIIU', - date: 1424383200000, - user_score: 8, - link: '/game/wii-u/kirby-and-the-rainbow-curse', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 56, - title: 'Pokemon Shuffle', - platform: '3DS', - date: 1424210400000, - user_score: 6.1, - link: '/game/3ds/pokemon-shuffle', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Puzzle', 'Matching'], - }, - { - meta_score: 89, - title: "The Legend of Zelda: Majora's Mask 3D", - platform: '3DS', - date: 1423778400000, - user_score: 8.9, - link: '/game/3ds/the-legend-of-zelda-majoras-mask-3d', - esrb_rating: 'E10+', - developers: ['GREZZO'], - genres: ['Fantasy', 'Action Adventure', 'Open-World'], - }, - { - meta_score: null, - title: 'Flipnote Studio 3D', - platform: '3DS', - date: 1423519200000, - user_score: 6.9, - link: '/game/3ds/flipnote-studio-3d', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: null, - title: "Hyrule Warriors: Majora's Mask Pack", - platform: 'WIIU', - date: 1423087200000, - user_score: 8, - link: '/game/wii-u/hyrule-warriors-majoras-mask-pack', - esrb_rating: '', - developers: ['Tecmo Koei Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 81, - title: 'Captain Toad: Treasure Tracker', - platform: 'WIIU', - date: 1417730400000, - user_score: 8.6, - link: '/game/wii-u/captain-toad-treasure-tracker', - esrb_rating: 'E', - developers: ['Nintendo EAD Tokyo '], - genres: ['Puzzle', 'Action', 'Platformer', '3D'], - }, - { - meta_score: null, - title: 'NES Remix Pack', - platform: 'WIIU', - date: 1417730400000, - user_score: 8.6, - link: '/game/wii-u/nes-remix-pack', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: null, - title: 'Hyrule Warriors: Twilight Princess Pack', - platform: 'WIIU', - date: 1416952800000, - user_score: 8.3, - link: '/game/wii-u/hyrule-warriors-twilight-princess-pack', - esrb_rating: 'T', - developers: ['Tecmo Koei Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 92, - title: 'Super Smash Bros. for Wii U', - platform: 'WIIU', - date: 1416520800000, - user_score: 8.9, - link: '/game/wii-u/super-smash-bros-for-wii-u', - esrb_rating: 'E10+', - developers: ['Bandai Namco Games'], - genres: ['Action', 'Fighting', 'Fighting', '3D', '2D', '2D', '3D'], - }, - { - meta_score: 82, - title: 'Pokemon Alpha Sapphire', - platform: '3DS', - date: 1416520800000, - user_score: 7.6, - link: '/game/3ds/pokemon-alpha-sapphire', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Japanese-Style', 'Trainer'], - }, - { - meta_score: 83, - title: 'Pokemon Omega Ruby', - platform: '3DS', - date: 1416520800000, - user_score: 7.5, - link: '/game/3ds/pokemon-omega-ruby', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Japanese-Style', 'Trainer'], - }, - { - meta_score: null, - title: 'Pokemon Omega Ruby/Alpha Sapphire Double Pack', - platform: '3DS', - date: 1416520800000, - user_score: 7.4, - link: '/game/3ds/pokemon-omega-rubyalpha-sapphire-double-pack', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Japanese-Style', 'Trainer'], - }, - { - meta_score: 87, - title: 'Mario Kart 8 DLC Pack 1', - platform: 'WIIU', - date: 1415829600000, - user_score: 8.2, - link: '/game/wii-u/mario-kart-8-dlc-pack-1', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Automobile'], - }, - { - meta_score: 69, - title: 'Ultimate NES Remix', - platform: '3DS', - date: 1415311200000, - user_score: 7.4, - link: '/game/3ds/ultimate-nes-remix', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 76, - title: 'Pokemon Art Academy', - platform: '3DS', - date: 1414098000000, - user_score: 7.8, - link: '/game/3ds/pokemon-art-academy', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'General', 'Edutainment'], - }, - { - meta_score: 86, - title: 'Bayonetta', - platform: 'WIIU', - date: 1414098000000, - user_score: 8.8, - link: '/game/wii-u/bayonetta', - esrb_rating: 'M', - developers: ['Bee Tribe'], - genres: ['Action', 'Fantasy', "Beat-'Em-Up", 'Action Adventure', 'Linear'], - }, - { - meta_score: 73, - title: 'Fantasy Life', - platform: '3DS', - date: 1414098000000, - user_score: 8.4, - link: '/game/3ds/fantasy-life', - esrb_rating: 'E10+', - developers: ['Level 5', 'Brownie Brown'], - genres: ['Role-Playing', 'General'], - }, - { - meta_score: null, - title: 'Bayonetta + Bayonetta 2', - platform: 'WIIU', - date: 1414098000000, - user_score: 8.2, - link: '/game/wii-u/bayonetta-+-bayonetta-2', - esrb_rating: 'M', - developers: ['PlatinumGames'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: null, - title: 'Hyrule Warriors: Master Quest Pack', - platform: 'WIIU', - date: 1413406800000, - user_score: 7.9, - link: '/game/wii-u/hyrule-warriors-master-quest-pack', - esrb_rating: '', - developers: ['Tecmo Koei Games'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 85, - title: 'Super Smash Bros. for Nintendo 3DS', - platform: '3DS', - date: 1412283600000, - user_score: 8.4, - link: '/game/3ds/super-smash-bros-for-nintendo-3ds', - esrb_rating: 'E10+', - developers: ['Bandai Namco Games'], - genres: ['Fighting', '3D', '2D', 'Action', 'Fighting', '2D', '3D'], - }, - { - meta_score: 76, - title: 'Hyrule Warriors', - platform: 'WIIU', - date: 1411678800000, - user_score: 8.3, - link: '/game/wii-u/hyrule-warriors', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", '3D'], - }, - { - meta_score: 91, - title: 'Bayonetta 2', - platform: 'WIIU', - date: 1411160400000, - user_score: 8.9, - link: '/game/wii-u/bayonetta-2', - esrb_rating: 'M', - developers: ['PlatinumGames'], - genres: ['Action Adventure', 'Fantasy', 'Fantasy', 'Linear'], - }, - { - meta_score: 79, - title: 'Professor Layton VS Phoenix Wright Ace Attorney', - platform: '3DS', - date: 1409259600000, - user_score: 8.2, - link: '/game/3ds/professor-layton-vs-phoenix-wright-ace-attorney', - esrb_rating: 'T', - developers: ['Level 5'], - genres: ['General', 'Puzzle', 'Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 65, - title: "Dedede's Drum Dash Deluxe", - platform: '3DS', - date: 1409259600000, - user_score: 7.3, - link: '/game/3ds/dededes-drum-dash-deluxe', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music'], - }, - { - meta_score: 66, - title: 'Kirby Fighters Deluxe', - platform: '3DS', - date: 1409259600000, - user_score: 6.1, - link: '/game/3ds/kirby-fighters-deluxe', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'The Mysterious Murasame Castle', - platform: '3DS', - date: 1407358800000, - user_score: null, - link: '/game/3ds/the-mysterious-murasame-castle', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'General'], - }, - { - meta_score: 80, - title: 'Pushmo World', - platform: 'WIIU', - date: 1403125200000, - user_score: 8, - link: '/game/wii-u/pushmo-world', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Logic'], - }, - { - meta_score: 75, - title: 'Inazuma Eleven Go: Shadow', - platform: '3DS', - date: 1402606800000, - user_score: 7.2, - link: '/game/3ds/inazuma-eleven-go-shadow', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 74, - title: 'Inazuma Eleven Go: Light', - platform: '3DS', - date: 1402606800000, - user_score: 7.6, - link: '/game/3ds/inazuma-eleven-go-light', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 71, - title: 'Tomodachi Life', - platform: '3DS', - date: 1402002000000, - user_score: 7.7, - link: '/game/3ds/tomodachi-life', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'General', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 88, - title: 'Mario Kart 8', - platform: 'WIIU', - date: 1401397200000, - user_score: 8.7, - link: '/game/wii-u/mario-kart-8', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Kart', 'Automobile'], - }, - { - meta_score: null, - title: 'Photos with Mario', - platform: '3DS', - date: 1400360400000, - user_score: 6.9, - link: '/game/3ds/photos-with-mario', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 80, - title: 'Kirby: Triple Deluxe', - platform: '3DS', - date: 1398978000000, - user_score: 8.6, - link: '/game/3ds/kirby-triple-deluxe', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['General', 'General', 'Action', 'Platformer', '2D'], - }, - { - meta_score: 78, - title: 'Mario Golf: World Tour', - platform: '3DS', - date: 1398978000000, - user_score: 8.1, - link: '/game/3ds/mario-golf-world-tour', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Individual', 'Golf', 'Arcade', 'Arcade'], - }, - { - meta_score: 73, - title: 'NES Remix 2', - platform: 'WIIU', - date: 1398373200000, - user_score: 8, - link: '/game/wii-u/nes-remix-2', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'General', 'Party / Minigame'], - }, - { - meta_score: 65, - title: 'Nintendo Pocket Football Club', - platform: '3DS', - date: 1397682000000, - user_score: 7.7, - link: '/game/3ds/nintendo-pocket-football-club', - esrb_rating: '', - developers: ['ParityBit'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 71, - title: 'Disney Magical World', - platform: '3DS', - date: 1397163600000, - user_score: 7.5, - link: '/game/3ds/disney-magical-world', - esrb_rating: 'E', - developers: ['h.a.n.d. Inc.'], - genres: ['Simulation', 'Miscellaneous', 'General', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 74, - title: "Rusty's Real Deal Baseball", - platform: '3DS', - date: 1396472400000, - user_score: 7.7, - link: '/game/3ds/rustys-real-deal-baseball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General'], - }, - { - meta_score: 70, - title: 'Pokemon Battle Trozei', - platform: '3DS', - date: 1395266400000, - user_score: 7.3, - link: '/game/3ds/pokemon-battle-trozei', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Miscellaneous', 'Puzzle', 'Matching'], - }, - { - meta_score: 64, - title: "Yoshi's New Island", - platform: '3DS', - date: 1394748000000, - user_score: 6.1, - link: '/game/3ds/yoshis-new-island', - esrb_rating: 'E', - developers: ['Arzest'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 81, - title: 'Professor Layton and the Azran Legacy', - platform: '3DS', - date: 1393538400000, - user_score: 8.1, - link: '/game/3ds/professor-layton-and-the-azran-legacy', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['General', 'Logic', 'Puzzle', 'Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 83, - title: 'Donkey Kong Country: Tropical Freeze', - platform: 'WIIU', - date: 1392933600000, - user_score: 8.9, - link: '/game/wii-u/donkey-kong-country-tropical-freeze', - esrb_rating: 'E', - developers: ['Retro Studios'], - genres: ['Platformer', '2D', 'Action', 'Platformer', '2D'], - }, - { - meta_score: 70, - title: 'Inazuma Eleven 3: Team Ogre Attacks!', - platform: '3DS', - date: 1392328800000, - user_score: 8, - link: '/game/3ds/inazuma-eleven-3-team-ogre-attacks!', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 70, - title: 'Steel Diver: Sub Wars', - platform: '3DS', - date: 1392242400000, - user_score: 7.6, - link: '/game/3ds/steel-diver-sub-wars', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Simulation', 'Submarine', 'Marine', 'Combat'], - }, - { - meta_score: 85, - title: 'Bravely Default', - platform: '3DS', - date: 1391724000000, - user_score: 8.4, - link: '/game/3ds/bravely-default', - esrb_rating: 'T', - developers: ['Silicon Studio'], - genres: ['Console-style RPG', 'Role-Playing', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Poke Transporter', - platform: '3DS', - date: 1391551200000, - user_score: null, - link: '/game/3ds/poke-transporter', - esrb_rating: '', - developers: ['Game Freak'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: null, - title: 'Pokemon Bank', - platform: '3DS', - date: 1391551200000, - user_score: 5.9, - link: '/game/3ds/pokemon-bank', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 49, - title: 'Chibi-Robo! Photo Finder', - platform: '3DS', - date: 1389218400000, - user_score: 7.6, - link: '/game/3ds/chibi-robo!-photo-finder', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Action', 'Action Adventure', 'General', 'Fantasy'], - }, - { - meta_score: 65, - title: 'Dr. Luigi', - platform: 'WIIU', - date: 1388440800000, - user_score: 7.3, - link: '/game/wii-u/dr-luigi', - esrb_rating: 'E', - developers: ['Arika', 'Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Stacking'], - }, - { - meta_score: 71, - title: 'NES Remix', - platform: 'WIIU', - date: 1387317600000, - user_score: 7.3, - link: '/game/wii-u/nes-remix', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'General', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Nintendo 3DS Guide: Louvre', - platform: '3DS', - date: 1385935200000, - user_score: null, - link: '/game/3ds/nintendo-3ds-guide-louvre', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 57, - title: 'Mario Party: Island Tour', - platform: '3DS', - date: 1385071200000, - user_score: 5.9, - link: '/game/3ds/mario-party-island-tour', - esrb_rating: 'E', - developers: ['Nintendo', 'Nd Cube'], - genres: ['Party', 'Miscellaneous', 'Party', 'Party / Minigame'], - }, - { - meta_score: 91, - title: 'The Legend of Zelda: A Link Between Worlds', - platform: '3DS', - date: 1385071200000, - user_score: 9, - link: '/game/3ds/the-legend-of-zelda-a-link-between-worlds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: [ - 'Action RPG', - 'Role-Playing', - 'Action Adventure', - 'General', - 'Action RPG', - 'Open-World', - ], - }, - { - meta_score: 93, - title: 'Super Mario 3D World', - platform: 'WIIU', - date: 1385071200000, - user_score: 8.9, - link: '/game/wii-u/super-mario-3d-world', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Platformer', '3D', 'Action', 'Platformer', '3D'], - }, - { - meta_score: 55, - title: 'Mario & Sonic at the Sochi 2014 Olympic Winter Games', - platform: 'WIIU', - date: 1384466400000, - user_score: 6.5, - link: '/game/wii-u/mario-sonic-at-the-sochi-2014-olympic-winter-games', - esrb_rating: 'E', - developers: ['Nintendo', 'Sega Sports R&D'], - genres: ['Sports', 'Olympic Sports', 'Olympic Sports', 'Individual', 'Athletics'], - }, - { - meta_score: 68, - title: 'Wii Sports Club', - platform: 'WIIU', - date: 1383775200000, - user_score: 7, - link: '/game/wii-u/wii-sports-club', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Sports', 'General', 'General', 'Individual', 'Athletics'], - }, - { - meta_score: 72, - title: 'Wii Fit U', - platform: 'WIIU', - date: 1383256800000, - user_score: 7.7, - link: '/game/wii-u/wii-fit-u', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Miscellaneous', 'General', 'Exercise / Fitness'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. U + New Super Luigi U', - platform: 'WIIU', - date: 1383256800000, - user_score: 8.7, - link: '/game/wii-u/new-super-mario-bros-u-+-new-super-luigi-u', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 65, - title: 'Wii Party U', - platform: 'WIIU', - date: 1382648400000, - user_score: 7.1, - link: '/game/wii-u/wii-party-u', - esrb_rating: 'E', - developers: ['Nd Cube'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 87, - title: 'Pokemon X', - platform: '3DS', - date: 1381525200000, - user_score: 7.5, - link: '/game/3ds/pokemon-x', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 88, - title: 'Pokemon Y', - platform: '3DS', - date: 1381525200000, - user_score: 7.5, - link: '/game/3ds/pokemon-y', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 70, - title: 'Inazuma Eleven 3: Lightning Bolt', - platform: '3DS', - date: 1380229200000, - user_score: 8.1, - link: '/game/3ds/inazuma-eleven-3-lightning-bolt', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 72, - title: 'Inazuma Eleven 3: Bomb Blast', - platform: '3DS', - date: 1380229200000, - user_score: 8.1, - link: '/game/3ds/inazuma-eleven-3-bomb-blast', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 90, - title: 'The Legend of Zelda: The Wind Waker HD', - platform: 'WIIU', - date: 1379624400000, - user_score: 9, - link: '/game/wii-u/the-legend-of-zelda-the-wind-waker-hd', - esrb_rating: 'E10+', - developers: ['Nintendo', 'HexaDrive'], - genres: ['Action Adventure', 'Fantasy', 'Fantasy', 'Open-World'], - }, - { - meta_score: 78, - title: 'The Wonderful 101', - platform: 'WIIU', - date: 1379192400000, - user_score: 8.6, - link: '/game/wii-u/the-wonderful-101', - esrb_rating: 'T', - developers: ['PlatinumGames'], - genres: ['Action', 'General', 'General', 'Platformer', '2D'], - }, - { - meta_score: 49, - title: 'Pokemon Rumble U', - platform: 'WIIU', - date: 1377723600000, - user_score: 5.2, - link: '/game/wii-u/pokemon-rumble-u', - esrb_rating: 'E', - developers: ['Ambrella'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '2D', '3D'], - }, - { - meta_score: 81, - title: 'Mario & Luigi: Dream Team', - platform: '3DS', - date: 1376168400000, - user_score: 8.3, - link: '/game/3ds/mario-luigi-dream-team', - esrb_rating: 'E10+', - developers: ['Alphadream Corporation'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: 70, - title: 'Art Academy: SketchPad', - platform: 'WIIU', - date: 1375995600000, - user_score: 6.3, - link: '/game/wii-u/art-academy-sketchpad', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: null, - title: 'Animal Crossing Plaza', - platform: 'WIIU', - date: 1375822800000, - user_score: 5.2, - link: '/game/wii-u/animal-crossing-plaza', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: 87, - title: 'Pikmin 3', - platform: 'WIIU', - date: 1375563600000, - user_score: 8.8, - link: '/game/wii-u/pikmin-3', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 61, - title: 'Game & Wario', - platform: 'WIIU', - date: 1371934800000, - user_score: 6.7, - link: '/game/wii-u/game-wario', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 77, - title: 'New Super Luigi U', - platform: 'WIIU', - date: 1371675600000, - user_score: 8, - link: '/game/wii-u/new-super-luigi-u', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 88, - title: 'Animal Crossing: New Leaf', - platform: '3DS', - date: 1370725200000, - user_score: 8.7, - link: '/game/3ds/animal-crossing-new-leaf', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 83, - title: 'Donkey Kong Country Returns 3D', - platform: '3DS', - date: 1369342800000, - user_score: 8.2, - link: '/game/3ds/donkey-kong-country-returns-3d', - esrb_rating: 'E', - developers: ['Monster Games Inc.'], - genres: ['Action', 'General', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Future Past 3', - platform: '3DS', - date: 1369256400000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-future-past-3', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Apotheosis', - platform: '3DS', - date: 1369256400000, - user_score: 7.5, - link: '/game/3ds/fire-emblem-awakening---apotheosis', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Future Past 2', - platform: '3DS', - date: 1368651600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-future-past-2', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 78, - title: 'Mario and Donkey Kong: Minis on the Move', - platform: '3DS', - date: 1368046800000, - user_score: 7.2, - link: '/game/3ds/mario-and-donkey-kong-minis-on-the-move', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Puzzle', 'Action', 'Platformer', 'Platformer', '3D', '3D'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Future Past 1', - platform: '3DS', - date: 1368046800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-future-past-1', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Hot Spring Scramble', - platform: '3DS', - date: 1368046800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---hot-spring-scramble', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Summer Scramble', - platform: '3DS', - date: 1367442000000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---summer-scramble', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Wii U Panorama View', - platform: 'WIIU', - date: 1366923600000, - user_score: 5.4, - link: '/game/wii-u/wii-u-panorama-view', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Radiant Hero', - platform: '3DS', - date: 1366837200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-radiant-hero', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Harvest Scramble', - platform: '3DS', - date: 1366837200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---harvest-scramble', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Roster Rescue', - platform: '3DS', - date: 1366837200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---roster-rescue', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 62, - title: 'LEGO City Undercover: The Chase Begins', - platform: '3DS', - date: 1366491600000, - user_score: 6.7, - link: '/game/3ds/lego-city-undercover-the-chase-begins', - esrb_rating: 'E10+', - developers: '["Traveller\'s Tales"]', - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Five-Anna Firefight', - platform: '3DS', - date: 1366232400000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---five-anna-firefight', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 68, - title: "Dillon's Rolling Western: The Last Ranger", - platform: '3DS', - date: 1365627600000, - user_score: 7, - link: '/game/3ds/dillons-rolling-western-the-last-ranger', - esrb_rating: 'E10+', - developers: ['Vanpool'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Rogues and Redeemers 3', - platform: '3DS', - date: 1365627600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---rogues-and-redeemers-3', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Wellspring of Truth', - platform: '3DS', - date: 1365627600000, - user_score: 7, - link: '/game/3ds/fire-emblem-awakening---the-wellspring-of-truth', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: "Fire Emblem: Awakening - Death's Embrace", - platform: '3DS', - date: 1365627600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---deaths-embrace', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Rogues and Redeemers 2', - platform: '3DS', - date: 1365022800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---rogues-and-redeemers-2', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 73, - title: 'HarmoKnight', - platform: '3DS', - date: 1364421600000, - user_score: 7.4, - link: '/game/3ds/harmoknight', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Ghost of Blade', - platform: '3DS', - date: 1364421600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---ghost-of-blade', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Rogues and Redeemers 1', - platform: '3DS', - date: 1364421600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---rogues-and-redeemers-1', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Smash Brethren 3', - platform: '3DS', - date: 1364421600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---smash-brethren-3', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 86, - title: "Luigi's Mansion: Dark Moon", - platform: '3DS', - date: 1364076000000, - user_score: 8.4, - link: '/game/3ds/luigis-mansion-dark-moon', - esrb_rating: 'E', - developers: ['Next Level Games'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 59, - title: 'Pokemon Mystery Dungeon: Gates to Infinity', - platform: '3DS', - date: 1364076000000, - user_score: 6.3, - link: '/game/3ds/pokemon-mystery-dungeon-gates-to-infinity', - esrb_rating: 'E', - developers: ['Nintendo', 'Spike Chunsoft'], - genres: ['General', 'Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Roguelike'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Smash Brethren 2', - platform: '3DS', - date: 1363816800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---smash-brethren-2', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 80, - title: 'LEGO City Undercover', - platform: 'WIIU', - date: 1363557600000, - user_score: 8.2, - link: '/game/wii-u/lego-city-undercover', - esrb_rating: 'E10+', - developers: ['TT Games'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy', 'Open-World'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Smash Brethren 1', - platform: '3DS', - date: 1363212000000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---smash-brethren-1', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Lost Bloodlines 3', - platform: '3DS', - date: 1363212000000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---lost-bloodlines-3', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - A Hard Miracle', - platform: '3DS', - date: 1363125600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---a-hard-miracle', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 62, - title: 'Kersploosh!', - platform: '3DS', - date: 1362607200000, - user_score: 7, - link: '/game/3ds/kersploosh!', - esrb_rating: 'E', - developers: ['Poisoft'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Lost Bloodlines 2', - platform: '3DS', - date: 1362607200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---lost-bloodlines-2', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Infinite Regalia', - platform: '3DS', - date: 1362607200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---infinite-regalia', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - EXPonential Growth', - platform: '3DS', - date: 1362002400000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---exponential-growth', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Irreconcilable Paths', - platform: '3DS', - date: 1362002400000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---irreconcilable-paths', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Lost Bloodlines 1', - platform: '3DS', - date: 1361397600000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---lost-bloodlines-1', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Wii Street U', - platform: 'WIIU', - date: 1360792800000, - user_score: 5.9, - link: '/game/wii-u/wii-street-u', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Champions of Yore 3', - platform: '3DS', - date: 1360792800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---champions-of-yore-3', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - The Golden Gaffe', - platform: '3DS', - date: 1360792800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-golden-gaffe', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: "Fire Emblem: Awakening - The Dead King's Lament", - platform: '3DS', - date: 1360792800000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---the-dead-kings-lament', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 69, - title: 'Brain Age: Concentration Training', - platform: '3DS', - date: 1360447200000, - user_score: 7.2, - link: '/game/3ds/brain-age-concentration-training', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Edutainment', 'Miscellaneous', 'Edutainment'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Champions of Yore 2', - platform: '3DS', - date: 1360188000000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---champions-of-yore-2', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 92, - title: 'Fire Emblem: Awakening', - platform: '3DS', - date: 1359928800000, - user_score: 9, - link: '/game/3ds/fire-emblem-awakening', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Fire Emblem: Awakening - Champions of Yore 1', - platform: '3DS', - date: 1359583200000, - user_score: null, - link: '/game/3ds/fire-emblem-awakening---champions-of-yore-1', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 68, - title: 'Tokyo Crash Mobs', - platform: '3DS', - date: 1358373600000, - user_score: 7.4, - link: '/game/3ds/tokyo-crash-mobs', - esrb_rating: 'E', - developers: ['Mitchell'], - genres: ['Miscellaneous', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Chase Mii', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/chase-mii', - esrb_rating: 'RP', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 78, - title: 'Fluidity: Spin Cycle', - platform: '3DS', - date: 1356559200000, - user_score: 6.6, - link: '/game/3ds/fluidity-spin-cycle', - esrb_rating: 'E', - developers: ['Curve Studios'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Mystery Adventure Pack', - platform: '3DS', - date: 1355954400000, - user_score: 7.7, - link: '/game/3ds/new-super-mario-bros-2-mystery-adventure-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Impossible Pack', - platform: '3DS', - date: 1355954400000, - user_score: 7.6, - link: '/game/3ds/new-super-mario-bros-2-impossible-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Coin Challenge Pack C', - platform: '3DS', - date: 1354658400000, - user_score: 7.6, - link: '/game/3ds/new-super-mario-bros-2-coin-challenge-pack-c', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Platform Panic Pack', - platform: '3DS', - date: 1354658400000, - user_score: 7, - link: '/game/3ds/new-super-mario-bros-2-platform-panic-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '3D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Gold Classics Pack', - platform: '3DS', - date: 1353967200000, - user_score: 7.1, - link: '/game/3ds/new-super-mario-bros-2-gold-classics-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 86, - title: 'Crashmo', - platform: '3DS', - date: 1353535200000, - user_score: 8.2, - link: '/game/3ds/crashmo', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Action'], - }, - { - meta_score: 84, - title: 'New Super Mario Bros. U', - platform: 'WIIU', - date: 1353189600000, - user_score: 8, - link: '/game/wii-u/new-super-mario-bros-u', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 69, - title: "Ninja Gaiden 3: Razor's Edge", - platform: 'WIIU', - date: 1353189600000, - user_score: 7.4, - link: '/game/wii-u/ninja-gaiden-3-razors-edge', - esrb_rating: 'M', - developers: ['Team Ninja'], - genres: ['Action', 'Action Adventure', 'Platformer', 'General', 'Platformer', '3D', '3D'], - }, - { - meta_score: 60, - title: 'SiNG Party', - platform: 'WIIU', - date: 1353189600000, - user_score: 6.1, - link: '/game/wii-u/sing-party', - esrb_rating: 'E10+', - developers: ['FreeStyleGames'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 77, - title: 'Nintendo Land', - platform: 'WIIU', - date: 1353189600000, - user_score: 7.9, - link: '/game/wii-u/nintendo-land', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 75, - title: 'Paper Mario: Sticker Star', - platform: '3DS', - date: 1352584800000, - user_score: 5.5, - link: '/game/3ds/paper-mario-sticker-star', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: [ - 'Action Adventure', - 'General', - 'Fantasy', - 'Role-Playing', - 'Console-style RPG', - 'Console-style RPG', - 'Japanese-Style', - ], - }, - { - meta_score: 59, - title: 'Pokedex 3D Pro', - platform: '3DS', - date: 1352325600000, - user_score: 4.3, - link: '/game/3ds/pokedex-3d-pro', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: 63, - title: 'Freakyforms Deluxe: Your Creations, Alive!', - platform: '3DS', - date: 1352066400000, - user_score: 7.5, - link: '/game/3ds/freakyforms-deluxe-your-creations-alive!', - esrb_rating: 'E', - developers: ['Asobism', 'Co. ltd.', 'Asobism.Co.', 'Ltd', 'Asobism'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 82, - title: 'Professor Layton and the Miracle Mask', - platform: '3DS', - date: 1351371600000, - user_score: 8.1, - link: '/game/3ds/professor-layton-and-the-miracle-mask', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Puzzle', 'Miscellaneous', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Coin Challenge Pack B', - platform: '3DS', - date: 1351112400000, - user_score: 7.1, - link: '/game/3ds/new-super-mario-bros-2-coin-challenge-pack-b', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Gold Mushroom Pack', - platform: '3DS', - date: 1351112400000, - user_score: 7.1, - link: '/game/3ds/new-super-mario-bros-2-gold-mushroom-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 76, - title: 'Style Savvy: Trendsetters', - platform: '3DS', - date: 1350853200000, - user_score: 7.6, - link: '/game/3ds/style-savvy-trendsetters', - esrb_rating: 'E', - developers: ['syn Sophia'], - genres: ['Simulation', 'Miscellaneous', 'General', 'General', 'Virtual', 'Career'], - }, - { - meta_score: 67, - title: 'Sparkle Snapshots 3D', - platform: '3DS', - date: 1350507600000, - user_score: null, - link: '/game/3ds/sparkle-snapshots-3d', - esrb_rating: '', - developers: ['Atlus Co.', 'Atlus'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Wii Sports/Wii Sports Resort', - platform: 'WII', - date: 1350248400000, - user_score: 8.4, - link: '/game/wii/wii-sportswii-sports-resort', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation', 'Compilation'], - }, - { - meta_score: 80, - title: 'Pokemon Black Version 2', - platform: 'DS', - date: 1349557200000, - user_score: 8.1, - link: '/game/ds/pokemon-black-version-2', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 80, - title: 'Pokemon White Version 2', - platform: 'DS', - date: 1349557200000, - user_score: 8, - link: '/game/ds/pokemon-white-version-2', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 54, - title: 'Pokemon Dream Radar', - platform: '3DS', - date: 1349557200000, - user_score: 5.9, - link: '/game/3ds/pokemon-dream-radar', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Action', 'General', 'Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Coin Challenge Pack A', - platform: '3DS', - date: 1349298000000, - user_score: 7.9, - link: '/game/3ds/new-super-mario-bros-2-coin-challenge-pack-a', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Gold Rush Pack', - platform: '3DS', - date: 1349298000000, - user_score: 7.3, - link: '/game/3ds/new-super-mario-bros-2-gold-rush-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'New Super Mario Bros. 2: Nerve-Wrack Pack', - platform: '3DS', - date: 1349298000000, - user_score: 7.5, - link: '/game/3ds/new-super-mario-bros-2-nerve-wrack-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 81, - title: 'Art Academy: Lessons for Everyone', - platform: '3DS', - date: 1349038800000, - user_score: 7.5, - link: '/game/3ds/art-academy-lessons-for-everyone', - esrb_rating: 'E', - developers: ['Nintendo', 'Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Art Academy: Lessons for Everyone', - platform: '3DS', - date: 1349038800000, - user_score: null, - link: '/game/3ds/art-academy-lessons-for-everyone', - esrb_rating: 'E', - developers: ['Nintendo', 'Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Crosswords Plus', - platform: '3DS', - date: 1349038800000, - user_score: 7.8, - link: '/game/3ds/crosswords-plus', - esrb_rating: 'E', - developers: ['Nintendo Software Technology'], - genres: ['Miscellaneous', 'Puzzle', 'General', 'Puzzle', 'Logic', 'General'], - }, - { - meta_score: 59, - title: 'Inazuma Eleven Strikers', - platform: 'WII', - date: 1348779600000, - user_score: 8.3, - link: '/game/wii/inazuma-eleven-strikers', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'General'], - }, - { - meta_score: 82, - title: "Kirby's Dream Collection: Special Edition", - platform: 'WII', - date: 1347742800000, - user_score: 8.9, - link: '/game/wii/kirbys-dream-collection-special-edition', - esrb_rating: 'E10+', - developers: ['HAL Labs'], - genres: ['Miscellaneous', 'Compilation', 'Compilation'], - }, - { - meta_score: 78, - title: 'New Super Mario Bros. 2', - platform: '3DS', - date: 1345323600000, - user_score: 7.1, - link: '/game/3ds/new-super-mario-bros-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 77, - title: 'Project Zero 2: Wii Edition', - platform: 'WII', - date: 1340917200000, - user_score: 8.4, - link: '/game/wii/project-zero-2-wii-edition', - esrb_rating: '', - developers: ['Koei Tecmo Games'], - genres: ['Action Adventure', 'Horror'], - }, - { - meta_score: 80, - title: 'Pokemon Conquest', - platform: 'DS', - date: 1339966800000, - user_score: 8.1, - link: '/game/ds/pokemon-conquest', - esrb_rating: 'E', - developers: ['Koei', 'Koei Tecmo Games'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'New Play Control! Pikmin 2', - platform: 'WII', - date: 1339275600000, - user_score: 8.7, - link: '/game/wii/new-play-control!-pikmin-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 69, - title: 'Mario Tennis Open', - platform: '3DS', - date: 1337461200000, - user_score: 6.9, - link: '/game/3ds/mario-tennis-open', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Individual', 'Tennis', 'Tennis'], - }, - { - meta_score: 54, - title: 'Spirit Camera: The Cursed Memoir', - platform: '3DS', - date: 1334264400000, - user_score: 6.4, - link: '/game/3ds/spirit-camera-the-cursed-memoir', - esrb_rating: 'T', - developers: ['Tecmo Koei Games'], - genres: ['Action Adventure', 'Horror', 'Horror', 'Survival'], - }, - { - meta_score: 76, - title: "Ketzal's Corridors", - platform: '3DS', - date: 1334178000000, - user_score: 7.6, - link: '/game/3ds/ketzals-corridors', - esrb_rating: 'E', - developers: ['Keys Factory'], - genres: ['General', 'Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Action'], - }, - { - meta_score: 92, - title: 'Xenoblade Chronicles', - platform: 'WII', - date: 1333659600000, - user_score: 9.1, - link: '/game/wii/xenoblade-chronicles', - esrb_rating: 'T', - developers: ['Monolith Soft'], - genres: ['Role-Playing', 'Action RPG', 'Console-style RPG', 'Action RPG'], - }, - { - meta_score: 83, - title: 'Kid Icarus: Uprising', - platform: '3DS', - date: 1332453600000, - user_score: 8.7, - link: '/game/3ds/kid-icarus-uprising', - esrb_rating: 'E10+', - developers: ['Opus', 'Project Sora'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 77, - title: '3D Classics: Kid Icarus', - platform: '3DS', - date: 1332453600000, - user_score: 7.4, - link: '/game/3ds/3d-classics-kid-icarus', - esrb_rating: 'E', - developers: ['Arika'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 74, - title: 'Inazuma Eleven 2: Firestorm', - platform: 'DS', - date: 1331848800000, - user_score: 8.6, - link: '/game/ds/inazuma-eleven-2-firestorm', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'General'], - }, - { - meta_score: 74, - title: 'Inazuma Eleven 2: Blizzard', - platform: 'DS', - date: 1331848800000, - user_score: 8.2, - link: '/game/ds/inazuma-eleven-2-blizzard', - esrb_rating: '', - developers: ['Level 5'], - genres: ['Sports', 'General'], - }, - { - meta_score: 73, - title: 'Mario Party 9', - platform: 'WII', - date: 1331416800000, - user_score: 6.8, - link: '/game/wii/mario-party-9', - esrb_rating: 'E', - developers: ['Nd Cube'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 60, - title: 'PokePark 2: Wonders Beyond', - platform: 'WII', - date: 1330293600000, - user_score: 7.7, - link: '/game/wii/pokepark-2-wonders-beyond', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Action Adventure', 'Adventure', 'General', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 65, - title: "Dillon's Rolling Western", - platform: '3DS', - date: 1329861600000, - user_score: 7.6, - link: '/game/3ds/dillons-rolling-western', - esrb_rating: 'E10+', - developers: ['Vanpool'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: 83, - title: 'Rhythm Heaven Fever', - platform: 'WII', - date: 1329084000000, - user_score: 8.3, - link: '/game/wii/rhythm-heaven-fever', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 46, - title: 'One Piece: Unlimited Cruise SP', - platform: '3DS', - date: 1328824800000, - user_score: 6.8, - link: '/game/3ds/one-piece-unlimited-cruise-sp', - esrb_rating: '', - developers: ['Bandai Namco Games'], - genres: ['Action', 'General'], - }, - { - meta_score: 74, - title: 'Sakura Samurai: Art of the Sword', - platform: '3DS', - date: 1328133600000, - user_score: 7.3, - link: '/game/3ds/sakura-samurai-art-of-the-sword', - esrb_rating: 'T', - developers: ['Grounding Inc.'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Pro Wrestling', - platform: 'WII', - date: null, - user_score: null, - link: '/game/wii/pro-wrestling', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', 'Wrestling'], - }, - { - meta_score: null, - title: "The Legend of Zelda: Link's Awakening DX", - platform: '3DS', - date: 1293832800000, - user_score: null, - link: '/game/3ds/the-legend-of-zelda-links-awakening-dx', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: null, - title: 'Super Mario Land', - platform: '3DS', - date: 1293832800000, - user_score: null, - link: '/game/3ds/super-mario-land', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Deer Drive Legends', - platform: '3DS', - date: null, - user_score: null, - link: '/game/3ds/deer-drive-legends', - esrb_rating: 'T', - developers: ['Raylight Studios'], - genres: ['Sports', 'Individual', 'Nature', 'Hunting', 'Hunting'], - }, - { - meta_score: null, - title: 'Swapnote', - platform: '3DS', - date: 1324504800000, - user_score: 7.3, - link: '/game/3ds/swapnote', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: 90, - title: 'Pushmo', - platform: '3DS', - date: 1323295200000, - user_score: 8.3, - link: '/game/3ds/pushmo', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Action'], - }, - { - meta_score: 68, - title: 'Fortune Street', - platform: 'WII', - date: 1323036000000, - user_score: 7.6, - link: '/game/wii/fortune-street', - esrb_rating: 'E', - developers: ['Marvelous AQL'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: 85, - title: 'Mario Kart 7', - platform: '3DS', - date: 1322949600000, - user_score: 8.2, - link: '/game/3ds/mario-kart-7', - esrb_rating: 'E', - developers: ['Retro Studios', 'Entertainment Analysis & Development Division'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Kart', 'Automobile'], - }, - { - meta_score: 93, - title: 'The Legend of Zelda: Skyward Sword', - platform: 'WII', - date: 1321740000000, - user_score: 8.1, - link: '/game/wii/the-legend-of-zelda-skyward-sword', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Fantasy', 'General', 'Fantasy', 'Action Adventure', 'Open-World'], - }, - { - meta_score: 77, - title: "3D Classics: Kirby's Adventure", - platform: '3DS', - date: 1321480800000, - user_score: 7.9, - link: '/game/3ds/3d-classics-kirbys-adventure', - esrb_rating: 'E', - developers: ['Arika'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 68, - title: 'Fossil Fighters: Champions', - platform: 'DS', - date: 1321221600000, - user_score: 7.9, - link: '/game/ds/fossil-fighters-champions', - esrb_rating: 'E', - developers: ['RED Entertainment', 'Artdink'], - genres: ['Role-Playing', 'General', 'General', 'Trainer'], - }, - { - meta_score: 90, - title: 'Super Mario 3D Land', - platform: '3DS', - date: 1321135200000, - user_score: 8.4, - link: '/game/3ds/super-mario-3d-land', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '3D', '3D'], - }, - { - meta_score: 68, - title: 'Freakyforms: Your Creations, Alive!', - platform: '3DS', - date: 1320876000000, - user_score: 7.7, - link: '/game/3ds/freakyforms-your-creations-alive!', - esrb_rating: 'E', - developers: ['Asobism', 'Co. ltd.', 'Asobism.Co.', 'Ltd', 'Asobism'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 77, - title: "Kirby's Return to Dream Land", - platform: 'WII', - date: 1319403600000, - user_score: 8.8, - link: '/game/wii/kirbys-return-to-dream-land', - esrb_rating: 'E10+', - developers: ['HAL Labs'], - genres: ['General', 'Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 56, - title: 'Pokemon Rumble Blast', - platform: '3DS', - date: 1319403600000, - user_score: 6.8, - link: '/game/3ds/pokemon-rumble-blast', - esrb_rating: 'E10+', - developers: ['Ambrella'], - genres: ['Action', 'General', "Beat-'Em-Up", "Beat-'Em-Up", '2D', '3D'], - }, - { - meta_score: 83, - title: 'Professor Layton and the Last Specter', - platform: 'DS', - date: 1318885200000, - user_score: 8.1, - link: '/game/ds/professor-layton-and-the-last-specter', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 74, - title: 'Tetris Axis', - platform: '3DS', - date: 1317502800000, - user_score: 7.1, - link: '/game/3ds/tetris-axis', - esrb_rating: 'E', - developers: ['Hudson Soft'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Stacking', 'Stacking'], - }, - { - meta_score: 85, - title: 'The Legend of Zelda: Four Swords Anniversary Edition', - platform: 'DS', - date: 1317157200000, - user_score: 7.5, - link: '/game/ds/the-legend-of-zelda-four-swords-anniversary-edition', - esrb_rating: 'E10+', - developers: ['GREZZO'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 68, - title: '3D Classics: TwinBee', - platform: '3DS', - date: 1316638800000, - user_score: 7.3, - link: '/game/3ds/3d-classics-twinbee', - esrb_rating: 'E', - developers: ['Arika'], - genres: [ - 'Action', - 'Shooter', - 'Shooter', - 'Scrolling', - 'Scrolling', - "Shoot-'Em-Up", - 'Vertical', - ], - }, - { - meta_score: 83, - title: 'Kirby Mass Attack', - platform: 'DS', - date: 1316379600000, - user_score: 7.9, - link: '/game/ds/kirby-mass-attack', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 77, - title: 'Dragon Quest Monsters: Joker 2', - platform: 'DS', - date: 1316379600000, - user_score: 7.6, - link: '/game/ds/dragon-quest-monsters-joker-2', - esrb_rating: 'E', - developers: ['TOSE'], - genres: [ - 'Role-Playing', - 'Console-style RPG', - 'Console-style RPG', - 'Japanese-Style', - 'Trainer', - ], - }, - { - meta_score: 81, - title: 'Star Fox 64 3D', - platform: '3DS', - date: 1315515600000, - user_score: 8.1, - link: '/game/3ds/star-fox-64-3d', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Q-Games'], - genres: ['Action', 'Shooter', 'Shooter', 'Rail', 'Rail'], - }, - { - meta_score: 74, - title: 'Inazuma Eleven', - platform: 'DS', - date: 1314306000000, - user_score: 7.9, - link: '/game/ds/inazuma-eleven', - esrb_rating: 'E', - developers: ['Level 5'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 37, - title: '3D Classics: Urban Champion', - platform: '3DS', - date: 1313614800000, - user_score: 4.8, - link: '/game/3ds/3d-classics-urban-champion', - esrb_rating: 'E10+', - developers: ['Arika'], - genres: ['Action', 'Fighting', 'Fighting', '2D', '2D'], - }, - { - meta_score: 56, - title: '3D Classics: Xevious', - platform: '3DS', - date: 1311195600000, - user_score: 5.8, - link: '/game/3ds/3d-classics-xevious', - esrb_rating: 'E', - developers: ['Arika'], - genres: [ - 'Action', - 'Shooter', - 'Shooter', - 'Scrolling', - 'Scrolling', - "Shoot-'Em-Up", - 'Vertical', - ], - }, - { - meta_score: null, - title: 'Nintendo Video', - platform: '3DS', - date: 1311195600000, - user_score: 5.9, - link: '/game/3ds/nintendo-video', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 65, - title: 'Mystery Case Files: The Malgrave Incident', - platform: 'WII', - date: 1309294800000, - user_score: 7.4, - link: '/game/wii/mystery-case-files-the-malgrave-incident', - esrb_rating: 'E', - developers: ['Sanzaru Games'], - genres: ['Miscellaneous', 'Puzzle', 'Hidden Object', 'Puzzle', 'General'], - }, - { - meta_score: 94, - title: 'The Legend of Zelda: Ocarina of Time 3D', - platform: '3DS', - date: 1308430800000, - user_score: 9, - link: '/game/3ds/the-legend-of-zelda-ocarina-of-time-3d', - esrb_rating: 'E10+', - developers: ['GREZZO'], - genres: [ - 'Miscellaneous', - 'Fantasy', - 'Fantasy', - 'Compilation', - 'Action Adventure', - 'Open-World', - ], - }, - { - meta_score: 60, - title: 'Wii Play: Motion', - platform: 'WII', - date: 1307912400000, - user_score: 6.4, - link: '/game/wii/wii-play-motion', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Good-Feel'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 69, - title: 'Pokedex 3D', - platform: '3DS', - date: 1307307600000, - user_score: 6.6, - link: '/game/3ds/pokedex-3d', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: null, - title: '3D Classics: Excitebike', - platform: '3DS', - date: 1307307600000, - user_score: 6.6, - link: '/game/3ds/3d-classics-excitebike', - esrb_rating: 'E', - developers: ['Arika'], - genres: [ - 'Driving', - 'Racing', - 'Arcade', - 'Motorcycle', - 'Other', - 'Automobile', - 'Motocross', - 'Motocross', - ], - }, - { - meta_score: 71, - title: 'Nintendogs + Cats: Golden Retriever & New Friends', - platform: '3DS', - date: 1301176800000, - user_score: 7.2, - link: '/game/3ds/nintendogs-+-cats-golden-retriever-new-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 71, - title: 'Pilotwings Resort', - platform: '3DS', - date: 1301176800000, - user_score: 7.2, - link: '/game/3ds/pilotwings-resort', - esrb_rating: 'E', - developers: ['Monster Games Inc.'], - genres: ['Simulation', 'Flight', 'Civilian Plane', 'Civilian Plane', 'Civilian'], - }, - { - meta_score: 58, - title: 'Steel Diver', - platform: '3DS', - date: 1301176800000, - user_score: 6.3, - link: '/game/3ds/steel-diver', - esrb_rating: 'E10+', - developers: ['Nintendo', 'Vitei'], - genres: ['Action', 'Simulation', 'General', 'Submarine', 'Submarine', 'Marine', 'Combat'], - }, - { - meta_score: 71, - title: 'Nintendogs + Cats: Toy Poodle & New Friends', - platform: '3DS', - date: 1301176800000, - user_score: 7.5, - link: '/game/3ds/nintendogs-+-cats-toy-poodle-new-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 71, - title: 'Nintendogs + Cats: French Bulldog & New Friends', - platform: '3DS', - date: 1301176800000, - user_score: 7.1, - link: '/game/3ds/nintendogs-+-cats-french-bulldog-new-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: null, - title: 'AR Games', - platform: '3DS', - date: 1301176800000, - user_score: 7.1, - link: '/game/3ds/ar-games', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Face Raiders', - platform: '3DS', - date: 1301176800000, - user_score: 7.2, - link: '/game/3ds/face-raiders', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'General', 'General', 'Shooter', 'Light Gun'], - }, - { - meta_score: null, - title: 'StreetPass Mii Plaza', - platform: '3DS', - date: 1301176800000, - user_score: 7.7, - link: '/game/3ds/streetpass-mii-plaza', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'General', 'General'], - }, - { - meta_score: null, - title: 'Nintendo 3DS', - platform: '3DS', - date: 1301176800000, - user_score: 8.1, - link: '/game/3ds/nintendo-3ds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Hardware', 'Console'], - }, - { - meta_score: null, - title: 'Mii Maker', - platform: '3DS', - date: 1301176800000, - user_score: 6.5, - link: '/game/3ds/mii-maker', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: null, - title: 'Nintendo 3DS Internet Browser', - platform: '3DS', - date: 1301176800000, - user_score: null, - link: '/game/3ds/nintendo-3ds-internet-browser', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Application'], - }, - { - meta_score: 87, - title: 'Pokemon Black Version', - platform: 'DS', - date: 1299362400000, - user_score: 7.9, - link: '/game/ds/pokemon-black-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 87, - title: 'Pokemon White Version', - platform: 'DS', - date: 1299362400000, - user_score: 7.9, - link: '/game/ds/pokemon-white-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 78, - title: 'Dragon Quest VI: Realms of Revelation', - platform: 'DS', - date: 1297634400000, - user_score: 8.3, - link: '/game/ds/dragon-quest-vi-realms-of-revelation', - esrb_rating: 'T', - developers: ['ArtePiazza'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: 64, - title: 'Mario Sports Mix', - platform: 'WII', - date: 1297029600000, - user_score: 7.9, - link: '/game/wii/mario-sports-mix', - esrb_rating: 'E', - developers: ['Square Enix'], - genres: ['Sports', 'General', 'General'], - }, - { - meta_score: 69, - title: 'Disaster: Day of Crisis', - platform: 'WII', - date: null, - user_score: 8.8, - link: '/game/wii/disaster-day-of-crisis', - esrb_rating: '', - developers: ['Monolith Soft'], - genres: ['Action', 'General'], - }, - { - meta_score: 66, - title: 'Another Code R: A Journey into Lost Memories', - platform: 'WII', - date: null, - user_score: 7.8, - link: '/game/wii/another-code-r-a-journey-into-lost-memories', - esrb_rating: '', - developers: ['Cing'], - genres: ['Adventure', 'General'], - }, - { - meta_score: null, - title: 'Fluidity', - platform: 'WII', - date: 1262296800000, - user_score: null, - link: '/game/wii/fluidity', - esrb_rating: 'E', - developers: ['Curve Studios'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '3D', '2D'], - }, - { - meta_score: null, - title: 'Mario Party 2', - platform: 'WII', - date: 1292796000000, - user_score: 8.6, - link: '/game/wii/mario-party-2', - esrb_rating: '', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 70, - title: 'Super Mario All-Stars: 25th Anniversary Edition', - platform: 'WII', - date: 1292104800000, - user_score: 7.8, - link: '/game/wii/super-mario-all-stars-25th-anniversary-edition', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation', 'Compilation'], - }, - { - meta_score: 86, - title: 'Fluidity', - platform: 'WII', - date: 1291586400000, - user_score: 7.8, - link: '/game/wii/fluidity', - esrb_rating: 'E', - developers: ['Curve Studios'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '3D', '2D'], - }, - { - meta_score: 79, - title: 'Golden Sun: Dark Dawn', - platform: 'DS', - date: 1290981600000, - user_score: 8.1, - link: '/game/ds/golden-sun-dark-dawn', - esrb_rating: 'E10+', - developers: ['Camelot Software Planning'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Snowpack Park', - platform: 'WII', - date: 1290376800000, - user_score: null, - link: '/game/wii/snowpack-park', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Simulation', 'General', 'General'], - }, - { - meta_score: 87, - title: 'Donkey Kong Country Returns', - platform: 'WII', - date: 1290290400000, - user_score: 8.6, - link: '/game/wii/donkey-kong-country-returns', - esrb_rating: 'E', - developers: ['Retro Studios'], - genres: ['Action', 'Adventure', 'General', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 79, - title: 'Mario vs. Donkey Kong: Mini-Land Mayhem', - platform: 'DS', - date: 1289685600000, - user_score: 8.1, - link: '/game/ds/mario-vs-donkey-kong-mini-land-mayhem', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 48, - title: 'FlingSmash', - platform: 'WII', - date: 1289080800000, - user_score: 7.4, - link: '/game/wii/flingsmash', - esrb_rating: 'E', - developers: ['Artoon'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: 62, - title: "PokePark Wii: Pikachu's Adventure", - platform: 'WII', - date: 1288648800000, - user_score: 7.7, - link: '/game/wii/pokepark-wii-pikachus-adventure', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Action Adventure', 'Adventure', 'General', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 75, - title: 'Art Academy', - platform: 'DS', - date: 1288040400000, - user_score: 7.6, - link: '/game/ds/art-academy', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 73, - title: 'ThruSpace', - platform: 'WII', - date: 1287349200000, - user_score: 8.3, - link: '/game/wii/thruspace', - esrb_rating: 'E', - developers: ['Keys Factory'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: null, - title: 'Snapdots', - platform: 'DS', - date: 1287349200000, - user_score: null, - link: '/game/ds/snapdots', - esrb_rating: 'E', - developers: ['D4 Enterprise'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: 86, - title: "Kirby's Epic Yarn", - platform: 'WII', - date: 1287262800000, - user_score: 8.5, - link: '/game/wii/kirbys-epic-yarn', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Adventure', 'General', 'Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 68, - title: 'Pokemon Ranger: Guardian Signs', - platform: 'DS', - date: 1286139600000, - user_score: 8.1, - link: '/game/ds/pokemon-ranger-guardian-signs', - esrb_rating: 'E', - developers: ['Creatures Inc.'], - genres: ['Role-Playing', 'General', 'General'], - }, - { - meta_score: 68, - title: 'Wii Party', - platform: 'WII', - date: 1286053200000, - user_score: 8, - link: '/game/wii/wii-party', - esrb_rating: 'E', - developers: ['Nd Cube'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: 55, - title: 'Samurai Warriors 3', - platform: 'WII', - date: 1285621200000, - user_score: 7.6, - link: '/game/wii/samurai-warriors-3', - esrb_rating: 'T', - developers: ['Omega Force'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '3D'], - }, - { - meta_score: null, - title: 'Nintendo Countdown Calendar', - platform: 'DS', - date: 1284930000000, - user_score: null, - link: '/game/ds/nintendo-countdown-calendar', - esrb_rating: '', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 86, - title: 'Professor Layton and the Unwound Future', - platform: 'DS', - date: 1284238800000, - user_score: 8.7, - link: '/game/ds/professor-layton-and-the-unwound-future', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 79, - title: 'Metroid: Other M', - platform: 'WII', - date: 1283202000000, - user_score: 6.7, - link: '/game/wii/metroid-other-m', - esrb_rating: 'T', - developers: ['Team Ninja'], - genres: [ - 'Action', - 'Action Adventure', - 'Shooter', - 'Sci-Fi', - 'Sci-Fi', - 'General', - 'Third-Person', - 'Sci-Fi', - ], - }, - { - meta_score: null, - title: 'Face Pilot: Fly With Your Nintendo DSi Camera!', - platform: 'DS', - date: 1280091600000, - user_score: null, - link: '/game/ds/face-pilot-fly-with-your-nintendo-dsi-camera!', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Simulation', 'General', 'General'], - }, - { - meta_score: 45, - title: 'AquaSpace', - platform: 'WII', - date: 1279486800000, - user_score: 5.6, - link: '/game/wii/aquaspace', - esrb_rating: 'E', - developers: ['Paon Corporation'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 87, - title: 'Dragon Quest IX: Sentinels of the Starry Skies', - platform: 'DS', - date: 1278795600000, - user_score: 8.6, - link: '/game/ds/dragon-quest-ix-sentinels-of-the-starry-skies', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: null, - title: 'Mario Tennis', - platform: 'WII', - date: 1277672400000, - user_score: null, - link: '/game/wii/mario-tennis', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Tennis'], - }, - { - meta_score: 87, - title: 'Sin & Punishment: Star Successor', - platform: 'WII', - date: 1277586000000, - user_score: 8.5, - link: '/game/wii/sin-punishment-star-successor', - esrb_rating: 'T', - developers: ['Treasure'], - genres: ['Action', 'General', 'Shooter', 'Shooter', 'Rail', 'Rail'], - }, - { - meta_score: 68, - title: 'Art Style: Rotozoa', - platform: 'WII', - date: 1277067600000, - user_score: null, - link: '/game/wii/art-style-rotozoa', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 74, - title: 'Spin Six', - platform: 'DS', - date: 1277067600000, - user_score: null, - link: '/game/ds/spin-six', - esrb_rating: 'E', - developers: ['Zener Works'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: 70, - title: '100 Classic Books', - platform: 'DS', - date: 1276462800000, - user_score: 6.5, - link: '/game/ds/100-classic-books', - esrb_rating: '', - developers: ['Genius Sonority Inc.'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: null, - title: "A Kappa's Trail", - platform: 'DS', - date: 1276462800000, - user_score: 8.1, - link: '/game/ds/a-kappas-trail', - esrb_rating: 'E', - developers: ['Brownie Brown'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 76, - title: 'Flametail', - platform: 'DS', - date: 1275858000000, - user_score: null, - link: '/game/ds/flametail', - esrb_rating: 'E', - developers: ['Mindware'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 82, - title: 'X-Scape', - platform: 'DS', - date: 1275253200000, - user_score: 7, - link: '/game/ds/x-scape', - esrb_rating: 'E10+', - developers: ['Q-Games'], - genres: [ - 'Simulation', - 'Action Adventure', - 'Sci-Fi', - 'Sci-Fi', - 'General', - 'Space', - 'Combat', - ], - }, - { - meta_score: null, - title: 'Phoenix Wright: Ace Attorney Episode 5: Rise From the Ashes', - platform: 'WII', - date: 1274734800000, - user_score: 8, - link: '/game/wii/phoenix-wright-ace-attorney-episode-5-rise-from-the-ashes', - esrb_rating: 'T', - developers: ['Capcom'], - genres: ['Adventure', 'First-Person', 'Modern'], - }, - { - meta_score: 76, - title: 'Art Style: light trax', - platform: 'WII', - date: 1274648400000, - user_score: null, - link: '/game/wii/art-style-light-trax', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 62, - title: 'Metal Torrent', - platform: 'DS', - date: 1274648400000, - user_score: 9.6, - link: '/game/ds/metal-torrent', - esrb_rating: 'E', - developers: ['Arika'], - genres: [ - 'Action', - 'Shooter', - 'Shooter', - 'Scrolling', - 'Scrolling', - "Shoot-'Em-Up", - 'Vertical', - ], - }, - { - meta_score: 97, - title: 'Super Mario Galaxy 2', - platform: 'WII', - date: 1274562000000, - user_score: 9.1, - link: '/game/wii/super-mario-galaxy-2', - esrb_rating: 'E', - developers: ['Nintendo EAD Tokyo '], - genres: ['Action', 'Platformer', 'Platformer', '3D', '3D'], - }, - { - meta_score: null, - title: 'Kirby Super Star', - platform: 'WII', - date: 1274043600000, - user_score: 8.5, - link: '/game/wii/kirby-super-star', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: "Looksley's Line Up", - platform: 'DS', - date: 1274043600000, - user_score: null, - link: '/game/ds/looksleys-line-up', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: [ - 'Miscellaneous', - 'Puzzle', - 'Puzzle', - 'Hidden Object', - 'General', - 'Puzzle', - 'General', - ], - }, - { - meta_score: 70, - title: 'Photo Dojo', - platform: 'DS', - date: 1273438800000, - user_score: 7, - link: '/game/ds/photo-dojo', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '2D'], - }, - { - meta_score: 83, - title: 'Picross 3D', - platform: 'DS', - date: 1272834000000, - user_score: 8.2, - link: '/game/ds/picross-3d', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Logic', 'Logic'], - }, - { - meta_score: null, - title: 'Game & Watch: Flagman', - platform: 'DS', - date: 1271624400000, - user_score: null, - link: '/game/ds/game-watch-flagman', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch: Ball', - platform: 'DS', - date: 1271624400000, - user_score: null, - link: '/game/ds/game-watch-ball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General', 'Arcade'], - }, - { - meta_score: null, - title: 'Game & Watch: Donkey Kong Jr.', - platform: 'DS', - date: 1271624400000, - user_score: 7.9, - link: '/game/ds/game-watch-donkey-kong-jr', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch: Vermin', - platform: 'DS', - date: 1270414800000, - user_score: null, - link: '/game/ds/game-watch-vermin', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Trivia / Game Show', 'Trivia / Game Show', 'Arcade'], - }, - { - meta_score: null, - title: 'Game & Watch: Helmet', - platform: 'DS', - date: 1270414800000, - user_score: null, - link: '/game/ds/game-watch-helmet', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch: Manhole', - platform: 'DS', - date: 1270414800000, - user_score: null, - link: '/game/ds/game-watch-manhole', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Grill-Off with Ultra Hand!', - platform: 'WII', - date: 1269982800000, - user_score: null, - link: '/game/wii/grill-off-with-ultra-hand!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch Collection 2', - platform: 'DS', - date: 1269982800000, - user_score: null, - link: '/game/ds/game-watch-collection-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation', 'Compilation'], - }, - { - meta_score: 73, - title: 'WarioWare D.I.Y. Showcase', - platform: 'WII', - date: 1269810000000, - user_score: 7.8, - link: '/game/wii/warioware-diy-showcase', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Nintendo DSi Metronome', - platform: 'DS', - date: 1269810000000, - user_score: 7.4, - link: '/game/ds/nintendo-dsi-metronome', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Nintendo DSi Instrument Tuner', - platform: 'DS', - date: 1269810000000, - user_score: null, - link: '/game/ds/nintendo-dsi-instrument-tuner', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 82, - title: 'WarioWare D.I.Y.', - platform: 'DS', - date: 1269727200000, - user_score: 8.2, - link: '/game/ds/warioware-diy', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: "America's Test Kitchen: Let's Get Cooking", - platform: 'WII', - date: 1269727200000, - user_score: null, - link: '/game/wii/americas-test-kitchen-lets-get-cooking', - esrb_rating: '', - developers: '', - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 87, - title: "America's Test Kitchen: Let's Get Cooking", - platform: 'DS', - date: 1269727200000, - user_score: 6.3, - link: '/game/ds/americas-test-kitchen-lets-get-cooking', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch: Judge', - platform: 'DS', - date: 1269208800000, - user_score: null, - link: '/game/ds/game-watch-judge', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Game & Watch: Chef', - platform: 'DS', - date: 1269208800000, - user_score: null, - link: '/game/ds/game-watch-chef', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: "Game & Watch: Mario's Cement Factory", - platform: 'DS', - date: 1269208800000, - user_score: null, - link: '/game/ds/game-watch-marios-cement-factory', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: 87, - title: 'Pokemon HeartGold Version', - platform: 'DS', - date: 1268517600000, - user_score: 9.1, - link: '/game/ds/pokemon-heartgold-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 87, - title: 'Pokemon SoulSilver Version', - platform: 'DS', - date: 1268517600000, - user_score: 9.2, - link: '/game/ds/pokemon-soulsilver-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 76, - title: 'Endless Ocean: Blue World', - platform: 'WII', - date: 1266789600000, - user_score: 8.6, - link: '/game/wii/endless-ocean-blue-world', - esrb_rating: 'E10+', - developers: ['Arika'], - genres: ['Adventure', 'General', 'General', '3D', 'Third-Person'], - }, - { - meta_score: null, - title: 'Aura-Aura Climber', - platform: 'DS', - date: 1266789600000, - user_score: 6, - link: '/game/ds/aura-aura-climber', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General', 'Arcade'], - }, - { - meta_score: 84, - title: 'Spotto!', - platform: 'DS', - date: 1266184800000, - user_score: 5.8, - link: '/game/ds/spotto!', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Action', 'Adventure', 'General', 'General'], - }, - { - meta_score: 73, - title: "Link 'n'Launch", - platform: 'DS', - date: 1265580000000, - user_score: null, - link: '/game/ds/link-n-launch', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'True Swing Golf Express', - platform: 'DS', - date: 1264975200000, - user_score: null, - link: '/game/ds/true-swing-golf-express', - esrb_rating: 'E', - developers: ['T&E Soft'], - genres: ['Sports', 'Traditional', 'Golf', 'Sim', 'Sim'], - }, - { - meta_score: 77, - title: 'Number Battle', - platform: 'DS', - date: 1264370400000, - user_score: 6.8, - link: '/game/ds/number-battle', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'Logic', 'General'], - }, - { - meta_score: 69, - title: 'Glory of Heracles', - platform: 'DS', - date: 1263765600000, - user_score: 7.4, - link: '/game/ds/glory-of-heracles', - esrb_rating: 'E10+', - developers: ['Paon Corporation'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: 82, - title: 'Starship Defense', - platform: 'DS', - date: 1263765600000, - user_score: 7.5, - link: '/game/ds/starship-defense', - esrb_rating: 'E', - developers: ['Q-Games'], - genres: ['Strategy', 'Real-Time', 'Sci-Fi', 'Sci-Fi', 'Defense'], - }, - { - meta_score: null, - title: 'Touch Solitaire', - platform: 'DS', - date: 1263160800000, - user_score: null, - link: '/game/ds/touch-solitaire', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Board Games', 'Board Games'], - }, - { - meta_score: 67, - title: 'Phoenix Wright: Ace Attorney', - platform: 'WII', - date: 1263160800000, - user_score: 8.7, - link: '/game/wii/phoenix-wright-ace-attorney', - esrb_rating: 'T', - developers: ['Capcom'], - genres: ['Adventure', 'First-Person', 'Visual Novel', 'Modern', 'Modern'], - }, - { - meta_score: 77, - title: 'Trajectile', - platform: 'DS', - date: 1262556000000, - user_score: null, - link: '/game/ds/trajectile', - esrb_rating: 'E', - developers: ['Q-Games'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Psychic Camera', - platform: 'DS', - date: 1261951200000, - user_score: null, - link: '/game/ds/master-of-illusion-express-psychic-camera', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Pilotwings', - platform: 'WII', - date: 1261951200000, - user_score: null, - link: '/game/wii/pilotwings', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Flight', 'Civilian Plane'], - }, - { - meta_score: null, - title: 'Super Smash Bros.', - platform: 'WII', - date: 1261346400000, - user_score: 7.8, - link: '/game/wii/super-smash-bros', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 56, - title: 'Eco Shooter: Plant 530', - platform: 'WII', - date: 1261346400000, - user_score: null, - link: '/game/wii/eco-shooter-plant-530', - esrb_rating: 'E10+', - developers: ['Intelligent Systems'], - genres: ['Action', 'Adventure', 'General', 'Shooter', 'First-Person', 'Fantasy', 'Arcade'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Matchmaker', - platform: 'DS', - date: 1260741600000, - user_score: null, - link: '/game/ds/master-of-illusion-express-matchmaker', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 87, - title: 'The Legend of Zelda: Spirit Tracks', - platform: 'DS', - date: 1260136800000, - user_score: 7.9, - link: '/game/ds/the-legend-of-zelda-spirit-tracks', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy', 'Fantasy', 'Open-World'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Mind Probe', - platform: 'DS', - date: 1259532000000, - user_score: null, - link: '/game/ds/master-of-illusion-express-mind-probe', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Electroplankton: Lumiloop', - platform: 'DS', - date: 1258927200000, - user_score: null, - link: '/game/ds/electroplankton-lumiloop', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Sun-Animalcule', - platform: 'DS', - date: 1258927200000, - user_score: null, - link: '/game/ds/electroplankton-sun-animalcule', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Varvoice', - platform: 'DS', - date: 1258927200000, - user_score: null, - link: '/game/ds/electroplankton-varvoice', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Marine-Crystals', - platform: 'DS', - date: 1258927200000, - user_score: null, - link: '/game/ds/electroplankton-marine-crystals', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Luminarrow', - platform: 'DS', - date: 1258927200000, - user_score: null, - link: '/game/ds/electroplankton-luminarrow', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Super Mario Kart', - platform: 'WII', - date: 1258927200000, - user_score: 7.2, - link: '/game/wii/super-mario-kart', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 59, - title: 'Pokemon Rumble', - platform: 'WII', - date: 1258322400000, - user_score: 8.2, - link: '/game/wii/pokemon-rumble', - esrb_rating: 'E10+', - developers: ['Ambrella'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '2D', '3D'], - }, - { - meta_score: 83, - title: 'Art Style: DIGIDRIVE', - platform: 'DS', - date: 1258322400000, - user_score: 6.8, - link: '/game/ds/art-style-digidrive', - esrb_rating: 'E', - developers: ['Q-Games'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'General'], - }, - { - meta_score: 87, - title: 'New Super Mario Bros. Wii', - platform: 'WII', - date: 1258236000000, - user_score: 8.4, - link: '/game/wii/new-super-mario-bros-wii', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'Electroplankton: Beatnes', - platform: 'DS', - date: 1257717600000, - user_score: null, - link: '/game/ds/electroplankton-beatnes', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Trapy', - platform: 'DS', - date: 1257717600000, - user_score: null, - link: '/game/ds/electroplankton-trapy', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Nanocarp', - platform: 'DS', - date: 1257717600000, - user_score: null, - link: '/game/ds/electroplankton-nanocarp', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Hanenbow', - platform: 'DS', - date: 1257717600000, - user_score: 7.5, - link: '/game/ds/electroplankton-hanenbow', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: null, - title: 'Electroplankton: Rec-Rec', - platform: 'DS', - date: 1257717600000, - user_score: null, - link: '/game/ds/electroplankton-rec-rec', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music Maker', 'Music Maker', 'Music'], - }, - { - meta_score: 70, - title: 'Excitebike: World Rally', - platform: 'WII', - date: 1257717600000, - user_score: 7.5, - link: '/game/wii/excitebike-world-rally', - esrb_rating: 'E', - developers: ['Monster Games Inc.'], - genres: ['Driving', 'Racing', 'Arcade', 'Motorcycle', 'Other', 'Motocross', 'Motocross'], - }, - { - meta_score: 73, - title: 'Style Savvy', - platform: 'DS', - date: 1257112800000, - user_score: 7.5, - link: '/game/ds/style-savvy', - esrb_rating: 'E', - developers: ['syn Sophia'], - genres: ['Simulation', 'General', 'General', 'Virtual', 'Career'], - }, - { - meta_score: null, - title: 'Sparkle Snapshots', - platform: 'DS', - date: 1257112800000, - user_score: null, - link: '/game/ds/sparkle-snapshots', - esrb_rating: '', - developers: ['Nintendo', 'Atlus'], - genres: ['Miscellaneous', 'Edutainment', 'General'], - }, - { - meta_score: null, - title: "Doc Louis's Punch-Out!!", - platform: 'WII', - date: 1256594400000, - user_score: 8.7, - link: '/game/wii/doc-louiss-punch-out!!', - esrb_rating: 'E10+', - developers: ['Next Level Games'], - genres: [ - 'Sports', - 'Traditional', - 'Individual', - 'Boxing', - 'Boxing', - 'Combat', - 'Boxing / Martial Arts', - ], - }, - { - meta_score: null, - title: 'PictureBook Games: The Royal Bluff', - platform: 'DS', - date: 1256508000000, - user_score: null, - link: '/game/ds/picturebook-games-the-royal-bluff', - esrb_rating: 'E', - developers: ['Nintendo', 'Grounding Inc.'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: null, - title: 'Crash-Course Domo', - platform: 'DS', - date: 1255899600000, - user_score: null, - link: '/game/ds/crash-course-domo', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Driving', 'Racing', 'Arcade', 'Other', 'Other'], - }, - { - meta_score: null, - title: 'Hard-Hat Domo', - platform: 'DS', - date: 1255899600000, - user_score: null, - link: '/game/ds/hard-hat-domo', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Adventure', 'Puzzle', 'Action', 'General'], - }, - { - meta_score: null, - title: 'Pro-Putt Domo', - platform: 'DS', - date: 1255899600000, - user_score: null, - link: '/game/ds/pro-putt-domo', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Sports', 'Traditional', 'Individual', 'Golf', 'Arcade', 'Arcade'], - }, - { - meta_score: null, - title: 'Rock-n-Roll Domo', - platform: 'DS', - date: 1255899600000, - user_score: null, - link: '/game/ds/rock-n-roll-domo', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: null, - title: 'White-Water Domo', - platform: 'DS', - date: 1255899600000, - user_score: null, - link: '/game/ds/white-water-domo', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Driving', 'Racing', 'Arcade', 'Snow / Water', 'Other', 'Snow / Water'], - }, - { - meta_score: 54, - title: 'Pokemon Mystery Dungeon: Explorers of Sky', - platform: 'DS', - date: 1255294800000, - user_score: 9, - link: '/game/ds/pokemon-mystery-dungeon-explorers-of-sky', - esrb_rating: 'E', - developers: ['ChunSoft'], - genres: ['Role-Playing', 'General', 'Console-style RPG', 'Console-style RPG', 'Roguelike'], - }, - { - meta_score: 74, - title: 'Pinball Pulse: The Ancients Beckon', - platform: 'DS', - date: 1255294800000, - user_score: null, - link: '/game/ds/pinball-pulse-the-ancients-beckon', - esrb_rating: 'E', - developers: ['Fuse Games Limited'], - genres: ['Action', 'Miscellaneous', 'Parlor', 'Pinball', 'Pinball'], - }, - { - meta_score: 80, - title: 'Wii Fit Plus', - platform: 'WII', - date: 1254603600000, - user_score: 7.6, - link: '/game/wii/wii-fit-plus', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: [ - 'Sports', - 'Miscellaneous', - 'Alternative', - 'General', - 'Exercise / Fitness', - 'Other', - ], - }, - { - meta_score: null, - title: 'Art Academy: Second Semester', - platform: 'DS', - date: 1254085200000, - user_score: null, - link: '/game/ds/art-academy-second-semester', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Clubhouse Games Express: Strategy Pack', - platform: 'DS', - date: 1253480400000, - user_score: null, - link: '/game/ds/clubhouse-games-express-strategy-pack', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: 79, - title: 'You, Me, and the Cubes', - platform: 'WII', - date: 1253480400000, - user_score: 7, - link: '/game/wii/you-me-and-the-cubes', - esrb_rating: 'E', - developers: ['fyto'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: 90, - title: "Mario & Luigi: Bowser's Inside Story", - platform: 'DS', - date: 1252875600000, - user_score: 8.8, - link: '/game/ds/mario-luigi-bowsers-inside-story', - esrb_rating: 'E', - developers: ['Alphadream Corporation'], - genres: [ - 'Role-Playing', - 'Action RPG', - 'Console-style RPG', - 'Console-style RPG', - 'Japanese-Style', - ], - }, - { - meta_score: null, - title: 'Art Academy: First Semester', - platform: 'DS', - date: 1252875600000, - user_score: 8, - link: '/game/ds/art-academy-first-semester', - esrb_rating: 'E', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Clubhouse Games Express: Family Favorites', - platform: 'DS', - date: 1252270800000, - user_score: null, - link: '/game/ds/clubhouse-games-express-family-favorites', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: null, - title: 'Puzzle League Express', - platform: 'DS', - date: 1251666000000, - user_score: null, - link: '/game/ds/puzzle-league-express', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 84, - title: 'Professor Layton and the Diabolical Box', - platform: 'DS', - date: 1251061200000, - user_score: 8.5, - link: '/game/ds/professor-layton-and-the-diabolical-box', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 91, - title: 'Metroid Prime Trilogy', - platform: 'WII', - date: 1251061200000, - user_score: 9.2, - link: '/game/wii/metroid-prime-trilogy', - esrb_rating: 'T', - developers: ['Retro Studios'], - genres: [ - 'Action', - 'Miscellaneous', - 'Shooter', - 'Compilation', - 'Compilation', - 'First-Person', - 'Sci-Fi', - ], - }, - { - meta_score: null, - title: 'Picture Book Games: Pop-Up Pursuit', - platform: 'WII', - date: 1250456400000, - user_score: null, - link: '/game/wii/picture-book-games-pop-up-pursuit', - esrb_rating: 'E', - developers: ['Grounding Inc.'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: null, - title: 'Brain Age Express: Sudoku', - platform: 'DS', - date: 1250456400000, - user_score: null, - link: '/game/ds/brain-age-express-sudoku', - esrb_rating: 'E', - developers: '', - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Logic', 'General'], - }, - { - meta_score: 93, - title: 'Flipnote Studio', - platform: 'DS', - date: 1250024400000, - user_score: 7.7, - link: '/game/ds/flipnote-studio', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: 70, - title: 'Fossil Fighters', - platform: 'DS', - date: 1249851600000, - user_score: 8.4, - link: '/game/ds/fossil-fighters', - esrb_rating: 'E', - developers: ['RED Entertainment'], - genres: ['Role-Playing', 'General', 'General', 'Trainer'], - }, - { - meta_score: 72, - title: "Rock N'Roll Climber", - platform: 'WII', - date: 1249851600000, - user_score: null, - link: '/game/wii/rock-n-roll-climber', - esrb_rating: 'E', - developers: ['Vitei'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Brain Age Express: Arts & Letters', - platform: 'DS', - date: 1249851600000, - user_score: null, - link: '/game/ds/brain-age-express-arts-letters', - esrb_rating: 'E', - developers: '', - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Art Style: precipice', - platform: 'DS', - date: 1249246800000, - user_score: 7.3, - link: '/game/ds/art-style-precipice', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: 80, - title: 'Wii Sports Resort', - platform: 'WII', - date: 1248555600000, - user_score: 8.3, - link: '/game/wii/wii-sports-resort', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'General', 'General', 'Individual', 'Athletics'], - }, - { - meta_score: 65, - title: 'Art Style: ZENGAGE', - platform: 'DS', - date: 1248037200000, - user_score: null, - link: '/game/ds/art-style-zengage', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: 77, - title: 'Art Style: BASE 10', - platform: 'DS', - date: 1246827600000, - user_score: null, - link: '/game/ds/art-style-base-10', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: 80, - title: 'Bit.Trip Core', - platform: 'WII', - date: 1246827600000, - user_score: 8.1, - link: '/game/wii/bittrip-core', - esrb_rating: 'E', - developers: ['Gaijin Games'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 80, - title: 'Art Style: BOXLIFE', - platform: 'DS', - date: 1245618000000, - user_score: 6.8, - link: '/game/ds/art-style-boxlife', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Mario Calculator', - platform: 'DS', - date: 1245013200000, - user_score: 6.3, - link: '/game/ds/mario-calculator', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'General', 'Edutainment'], - }, - { - meta_score: null, - title: 'Mario Clock', - platform: 'DS', - date: 1245013200000, - user_score: 6, - link: '/game/ds/mario-clock', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: 82, - title: 'Mario vs. Donkey Kong: Minis March Again!', - platform: 'DS', - date: 1244408400000, - user_score: 7.9, - link: '/game/ds/mario-vs-donkey-kong-minis-march-again!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 75, - title: 'The Legendary Starfy', - platform: 'DS', - date: 1244322000000, - user_score: 8.4, - link: '/game/ds/the-legendary-starfy', - esrb_rating: 'E', - developers: ['TOSE'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 69, - title: 'Personal Trainer: Walking', - platform: 'DS', - date: 1243285200000, - user_score: 7.3, - link: '/game/ds/personal-trainer-walking', - esrb_rating: 'E', - developers: ['Nintendo', 'Creatures Inc.'], - genres: ['Miscellaneous', 'General', 'Exercise / Fitness'], - }, - { - meta_score: null, - title: 'Photo Clock', - platform: 'DS', - date: 1243198800000, - user_score: null, - link: '/game/ds/photo-clock', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: 86, - title: 'Punch-Out!!', - platform: 'WII', - date: 1242594000000, - user_score: 8.6, - link: '/game/wii/punch-out!!', - esrb_rating: 'E10+', - developers: ['Next Level Games'], - genres: [ - 'Sports', - 'Traditional', - 'Individual', - 'Boxing', - 'Boxing', - 'Combat', - 'Boxing / Martial Arts', - ], - }, - { - meta_score: 83, - title: 'Art Style: PiCTOBiTS', - platform: 'DS', - date: 1242594000000, - user_score: 7.5, - link: '/game/ds/art-style-pictobits', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: null, - title: "The Legend of Zelda: Majora's Mask", - platform: 'WII', - date: 1242594000000, - user_score: 8.7, - link: '/game/wii/the-legend-of-zelda-majoras-mask', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 78, - title: 'New Play Control! Donkey Kong Jungle Beat', - platform: 'WII', - date: 1241384400000, - user_score: 8.5, - link: '/game/wii/new-play-control!-donkey-kong-jungle-beat', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'Animal Crossing Calculator', - platform: 'DS', - date: 1241384400000, - user_score: null, - link: '/game/ds/animal-crossing-calculator', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Application'], - }, - { - meta_score: null, - title: 'Animal Crossing Clock', - platform: 'DS', - date: 1241384400000, - user_score: null, - link: '/game/ds/animal-crossing-clock', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Application'], - }, - { - meta_score: 51, - title: 'Paper Airplane Chase', - platform: 'DS', - date: 1240779600000, - user_score: 7.2, - link: '/game/ds/paper-airplane-chase', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Clubhouse Games Express: Card Classics', - platform: 'DS', - date: 1240779600000, - user_score: null, - link: '/game/ds/clubhouse-games-express-card-classics', - esrb_rating: 'T', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Board Games', 'Board Games', 'Board / Card Game'], - }, - { - meta_score: 76, - title: 'Dr. Mario Express', - platform: 'DS', - date: 1240174800000, - user_score: 7.4, - link: '/game/ds/dr-mario-express', - esrb_rating: 'E', - developers: ['Arika', 'Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'Matching', 'General'], - }, - { - meta_score: 77, - title: 'Excitebots: Trick Racing', - platform: 'WII', - date: 1240174800000, - user_score: 8.1, - link: '/game/wii/excitebots-trick-racing', - esrb_rating: 'E', - developers: ['Monster Games Inc.'], - genres: ['Driving', 'Racing', 'General', 'Arcade', 'Arcade', 'Automobile'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Deep Psyche', - platform: 'DS', - date: 1240174800000, - user_score: null, - link: '/game/ds/master-of-illusion-express-deep-psyche', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Shuffle Games', - platform: 'DS', - date: 1239570000000, - user_score: null, - link: '/game/ds/master-of-illusion-express-shuffle-games', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 83, - title: 'Rhythm Heaven', - platform: 'DS', - date: 1238878800000, - user_score: 8.4, - link: '/game/ds/rhythm-heaven', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 70, - title: 'Art Style: AQUIA', - platform: 'DS', - date: 1238878800000, - user_score: 7.3, - link: '/game/ds/art-style-aquia', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Nintendo DSi Browser', - platform: 'DS', - date: 1238878800000, - user_score: null, - link: '/game/ds/nintendo-dsi-browser', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Web Browser', 'Application'], - }, - { - meta_score: null, - title: 'Master of Illusion Express: Funny Face', - platform: 'DS', - date: 1238878800000, - user_score: null, - link: '/game/ds/master-of-illusion-express-funny-face', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 71, - title: 'Bird & Beans', - platform: 'DS', - date: 1238878800000, - user_score: 7.8, - link: '/game/ds/bird-beans', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'General', 'Arcade'], - }, - { - meta_score: 69, - title: 'Brain Age Express: Math', - platform: 'DS', - date: 1238878800000, - user_score: null, - link: '/game/ds/brain-age-express-math', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 53, - title: 'WarioWare: Snapped!', - platform: 'DS', - date: 1238878800000, - user_score: 4.1, - link: '/game/ds/warioware-snapped!', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: [ - 'Miscellaneous', - 'Puzzle', - 'Puzzle', - 'General', - 'Puzzle', - 'Party / Minigame', - 'General', - ], - }, - { - meta_score: null, - title: 'Super Punch-Out!!', - platform: 'WII', - date: 1238360400000, - user_score: 8.9, - link: '/game/wii/super-punch-out!!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Boxing'], - }, - { - meta_score: 75, - title: 'Bonsai Barber', - platform: 'WII', - date: 1238360400000, - user_score: 7.4, - link: '/game/wii/bonsai-barber', - esrb_rating: 'E', - developers: ['Zoonami Ltd.'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 83, - title: 'Pokemon Platinum Version', - platform: 'DS', - date: 1237672800000, - user_score: 8.9, - link: '/game/ds/pokemon-platinum-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 80, - title: 'Bit.Trip Beat', - platform: 'WII', - date: 1237154400000, - user_score: 8.3, - link: '/game/wii/bittrip-beat', - esrb_rating: 'E', - developers: ['Gaijin Games'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 77, - title: 'New Play Control! Pikmin', - platform: 'WII', - date: 1236549600000, - user_score: 8.4, - link: '/game/wii/new-play-control!-pikmin', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: 65, - title: 'New Play Control! Mario Power Tennis', - platform: 'WII', - date: 1236549600000, - user_score: 7.6, - link: '/game/wii/new-play-control!-mario-power-tennis', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Individual', 'Tennis', 'Tennis'], - }, - { - meta_score: 81, - title: 'Fire Emblem: Shadow Dragon', - platform: 'DS', - date: 1234735200000, - user_score: 7.1, - link: '/game/ds/fire-emblem-shadow-dragon', - esrb_rating: 'E10+', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: 56, - title: 'Lonpos', - platform: 'WII', - date: 1233525600000, - user_score: null, - link: '/game/wii/lonpos', - esrb_rating: 'E', - developers: ['Genki'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 63, - title: 'Personal Trainer: Math', - platform: 'DS', - date: 1231797600000, - user_score: null, - link: '/game/ds/personal-trainer-math', - esrb_rating: 'E', - developers: ['Jupiter Corporation'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: "Kirby's Dream Land 3", - platform: 'WII', - date: 1231106400000, - user_score: 8, - link: '/game/wii/kirbys-dream-land-3', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 85, - title: "Maboshi's Arcade", - platform: 'WII', - date: 1230501600000, - user_score: 7.9, - link: '/game/wii/maboshis-arcade', - esrb_rating: 'E', - developers: ['Mindware'], - genres: ['Miscellaneous', 'Puzzle', 'Action', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: null, - title: "StarTropics II: Zoda's Revenge", - platform: 'WII', - date: 1230501600000, - user_score: 8.6, - link: '/game/wii/startropics-ii-zodas-revenge', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Modern'], - }, - { - meta_score: null, - title: 'Game & Watch Collection', - platform: 'DS', - date: 1229292000000, - user_score: null, - link: '/game/ds/game-watch-collection', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation', 'Compilation'], - }, - { - meta_score: 81, - title: 'Personal Trainer: Cooking', - platform: 'DS', - date: 1227477600000, - user_score: 8.1, - link: '/game/ds/personal-trainer-cooking', - esrb_rating: 'E', - developers: ['indieszero'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 73, - title: 'Animal Crossing: City Folk', - platform: 'WII', - date: 1226786400000, - user_score: 7.9, - link: '/game/wii/animal-crossing-city-folk', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 68, - title: 'Pokemon Ranger: Shadows of Almia', - platform: 'DS', - date: 1226268000000, - user_score: 7.9, - link: '/game/ds/pokemon-ranger-shadows-of-almia', - esrb_rating: 'E', - developers: ['HAL Labs', 'Creatures Inc.'], - genres: ['Role-Playing', 'General', 'General'], - }, - { - meta_score: 70, - title: 'Art Style: ROTOHEX', - platform: 'WII', - date: 1225058400000, - user_score: null, - link: '/game/wii/art-style-rotohex', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 63, - title: 'Wii Music', - platform: 'WII', - date: 1224450000000, - user_score: 4.8, - link: '/game/wii/wii-music', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 73, - title: 'Art Style: CUBELLO', - platform: 'WII', - date: 1223845200000, - user_score: 7.6, - link: '/game/wii/art-style-cubello', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Mario Golf', - platform: 'WII', - date: 1223240400000, - user_score: null, - link: '/game/wii/mario-golf', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Golf', 'Arcade'], - }, - { - meta_score: 82, - title: 'Art Style: ORBIENT', - platform: 'WII', - date: 1222635600000, - user_score: 8.2, - link: '/game/wii/art-style-orbient', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: 78, - title: 'Wario Land: Shake It!', - platform: 'WII', - date: 1222030800000, - user_score: 8.5, - link: '/game/wii/wario-land-shake-it!', - esrb_rating: 'E', - developers: ['Good-Feel'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 76, - title: 'Kirby Super Star Ultra', - platform: 'DS', - date: 1222030800000, - user_score: 8.8, - link: '/game/ds/kirby-super-star-ultra', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 65, - title: 'Mystery Case Files: MillionHeir', - platform: 'DS', - date: 1220821200000, - user_score: null, - link: '/game/ds/mystery-case-files-millionheir', - esrb_rating: 'E', - developers: ['Griptonite Games'], - genres: ['Miscellaneous', 'Adventure', 'Puzzle', 'General', 'Hidden Object', 'Puzzle'], - }, - { - meta_score: null, - title: 'Super Mario RPG: Legend of the Seven Stars', - platform: 'WII', - date: 1220216400000, - user_score: 8.9, - link: '/game/wii/super-mario-rpg-legend-of-the-seven-stars', - esrb_rating: 'E', - developers: ['SquareSoft'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: null, - title: 'Clu Clu Land', - platform: 'WII', - date: 1220216400000, - user_score: 8.4, - link: '/game/wii/clu-clu-land', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General'], - }, - { - meta_score: 69, - title: 'Mario Super Sluggers', - platform: 'WII', - date: 1219611600000, - user_score: 7.9, - link: '/game/wii/mario-super-sluggers', - esrb_rating: 'E', - developers: ['Namco Bandai Games'], - genres: ['Sports', 'Traditional', 'Team', 'Baseball', 'Arcade', 'Arcade'], - }, - { - meta_score: null, - title: 'Donkey Kong 3', - platform: 'WII', - date: 1215982800000, - user_score: null, - link: '/game/wii/donkey-kong-3', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General', 'Platformer', '2D'], - }, - { - meta_score: 70, - title: 'Magnetica Twist', - platform: 'WII', - date: 1214773200000, - user_score: 7.8, - link: '/game/wii/magnetica-twist', - esrb_rating: 'E', - developers: ['Mitchell'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'Matching', 'General'], - }, - { - meta_score: 47, - title: 'My Pokemon Ranch', - platform: 'WII', - date: 1212958800000, - user_score: 5.3, - link: '/game/wii/my-pokemon-ranch', - esrb_rating: 'E', - developers: ['Ambrella'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 72, - title: 'Dr. Mario Online RX', - platform: 'WII', - date: 1211749200000, - user_score: 8.2, - link: '/game/wii/dr-mario-online-rx', - esrb_rating: 'E', - developers: ['Arika', 'Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: 80, - title: 'Wii Fit', - platform: 'WII', - date: 1211144400000, - user_score: 7.7, - link: '/game/wii/wii-fit', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Miscellaneous', 'General', 'Exercise / Fitness'], - }, - { - meta_score: 67, - title: 'CrossworDS', - platform: 'DS', - date: 1209934800000, - user_score: 7.3, - link: '/game/ds/crosswords', - esrb_rating: 'E', - developers: ['Nuevo Retro Games'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Logic', 'General'], - }, - { - meta_score: null, - title: 'Pokemon Puzzle League', - platform: 'WII', - date: 1209934800000, - user_score: 7.9, - link: '/game/wii/pokemon-puzzle-league', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Matching'], - }, - { - meta_score: 82, - title: 'Mario Kart Wii', - platform: 'WII', - date: 1209243600000, - user_score: 8.5, - link: '/game/wii/mario-kart-wii', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Kart', 'Automobile'], - }, - { - meta_score: 59, - title: 'Pokemon Mystery Dungeon: Explorers of Darkness', - platform: 'DS', - date: 1208638800000, - user_score: 8.6, - link: '/game/ds/pokemon-mystery-dungeon-explorers-of-darkness', - esrb_rating: 'E', - developers: ['ChunSoft'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Roguelike'], - }, - { - meta_score: 60, - title: 'Pokemon Mystery Dungeon: Explorers of Time', - platform: 'DS', - date: 1208638800000, - user_score: 8.4, - link: '/game/ds/pokemon-mystery-dungeon-explorers-of-time', - esrb_rating: 'E', - developers: ['ChunSoft'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Roguelike'], - }, - { - meta_score: null, - title: "Yoshi's Cookie", - platform: 'WII', - date: 1207515600000, - user_score: null, - link: '/game/wii/yoshis-cookie', - esrb_rating: 'E', - developers: ['Bullet Proof Software'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: "Cruis'n USA", - platform: 'WII', - date: 1206910800000, - user_score: 8.6, - link: '/game/wii/cruisn-usa', - esrb_rating: 'E', - developers: ['Midway'], - genres: ['Driving', 'Racing', 'Arcade'], - }, - { - meta_score: 93, - title: 'Super Smash Bros. Brawl', - platform: 'WII', - date: 1205013600000, - user_score: 8.8, - link: '/game/wii/super-smash-bros-brawl', - esrb_rating: 'T', - developers: ['Game Arts'], - genres: ['Action', 'Fighting', 'Fighting', '3D', '2D', '3D'], - }, - { - meta_score: null, - title: 'Kirby 64: The Crystal Shards', - platform: 'WII', - date: 1203890400000, - user_score: 8.6, - link: '/game/wii/kirby-64-the-crystal-shards', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 85, - title: 'Professor Layton and the Curious Village', - platform: 'DS', - date: 1202594400000, - user_score: 8.4, - link: '/game/ds/professor-layton-and-the-curious-village', - esrb_rating: 'E', - developers: ['Level 5'], - genres: [ - 'Miscellaneous', - 'Adventure', - 'Puzzle', - 'Edutainment', - 'General', - 'Puzzle', - 'General', - ], - }, - { - meta_score: null, - title: '1080: TenEighty Snowboarding', - platform: 'WII', - date: 1201471200000, - user_score: 8.6, - link: '/game/wii/1080-teneighty-snowboarding', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Alternative', 'Snowboarding'], - }, - { - meta_score: 70, - title: 'Mario & Sonic at the Olympic Games', - platform: 'DS', - date: 1200952800000, - user_score: 7, - link: '/game/ds/mario-sonic-at-the-olympic-games', - esrb_rating: 'E', - developers: ['Sega', 'Nintendo', 'Sega Sports R&D'], - genres: ['Sports', 'Olympic Sports', 'Olympic Sports', 'Individual', 'Athletics'], - }, - { - meta_score: 72, - title: 'Endless Ocean', - platform: 'WII', - date: 1200866400000, - user_score: 8.2, - link: '/game/wii/endless-ocean', - esrb_rating: 'E', - developers: ['Arika'], - genres: ['Adventure', 'General', 'General', '3D', 'Third-Person'], - }, - { - meta_score: null, - title: 'Adventures of Lolo 2', - platform: 'WII', - date: 1200866400000, - user_score: null, - link: '/game/wii/adventures-of-lolo-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Action'], - }, - { - meta_score: 86, - title: 'Advance Wars: Days of Ruin', - platform: 'DS', - date: 1200866400000, - user_score: 8.5, - link: '/game/ds/advance-wars-days-of-ruin', - esrb_rating: 'E10+', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Modern', 'Modern', 'Tactics'], - }, - { - meta_score: null, - title: 'StarTropics', - platform: 'WII', - date: 1199656800000, - user_score: 8.8, - link: '/game/wii/startropics', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Modern'], - }, - { - meta_score: null, - title: "Donkey Kong Country 3: Dixie Kong's Double Trouble", - platform: 'WII', - date: 1198447200000, - user_score: 8.4, - link: '/game/wii/donkey-kong-country-3-dixie-kongs-double-trouble', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Pokemon Snap', - platform: 'WII', - date: 1197237600000, - user_score: 7.8, - link: '/game/wii/pokemon-snap', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Action', 'General'], - }, - { - meta_score: 69, - title: 'Master of Illusion', - platform: 'DS', - date: 1196028000000, - user_score: null, - link: '/game/ds/master-of-illusion', - esrb_rating: 'E', - developers: ['Eighting', 'Tenyo'], - genres: [ - 'Miscellaneous', - 'Puzzle', - 'Puzzle', - 'General', - 'Puzzle', - 'Application', - 'General', - ], - }, - { - meta_score: null, - title: 'Vegas Stakes', - platform: 'WII', - date: 1196028000000, - user_score: null, - link: '/game/wii/vegas-stakes', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Miscellaneous', 'Parlor', 'Gambling'], - }, - { - meta_score: 72, - title: 'Mario Party DS', - platform: 'DS', - date: 1195423200000, - user_score: 7.8, - link: '/game/ds/mario-party-ds', - esrb_rating: 'E', - developers: ['Hudson Soft'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Wrecking Crew', - platform: 'WII', - date: 1195423200000, - user_score: null, - link: '/game/wii/wrecking-crew', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 68, - title: "Link's Crossbow Training", - platform: 'WII', - date: 1195423200000, - user_score: 7.1, - link: '/game/wii/links-crossbow-training', - esrb_rating: 'T', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Shooter', 'Light Gun', 'Light Gun'], - }, - { - meta_score: 97, - title: 'Super Mario Galaxy', - platform: 'WII', - date: 1194818400000, - user_score: 9.1, - link: '/game/wii/super-mario-galaxy', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '3D', '3D'], - }, - { - meta_score: null, - title: 'Volleyball', - platform: 'WII', - date: 1194818400000, - user_score: null, - link: '/game/wii/volleyball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Volleyball'], - }, - { - meta_score: 67, - title: 'Mario & Sonic at the Olympic Games', - platform: 'WII', - date: 1194300000000, - user_score: 7.6, - link: '/game/wii/mario-sonic-at-the-olympic-games', - esrb_rating: 'E', - developers: ['Sega', 'Nintendo', 'Sega Sports R&D'], - genres: ['Sports', 'Olympic Sports', 'Olympic Sports', 'Individual', 'Athletics'], - }, - { - meta_score: 78, - title: 'Fire Emblem: Radiant Dawn', - platform: 'WII', - date: 1194213600000, - user_score: 8.9, - link: '/game/wii/fire-emblem-radiant-dawn', - esrb_rating: 'E10+', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'Fantasy', 'Tactics'], - }, - { - meta_score: null, - title: 'Super Mario Bros. 3', - platform: 'WII', - date: 1194213600000, - user_score: 9, - link: '/game/wii/super-mario-bros-3', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 75, - title: 'Battalion Wars 2', - platform: 'WII', - date: 1193608800000, - user_score: 8.2, - link: '/game/wii/battalion-wars-2', - esrb_rating: 'T', - developers: ['Kuju Entertainment'], - genres: ['Strategy', 'Real-Time', 'Military', 'Military', 'Tactics'], - }, - { - meta_score: 59, - title: 'Flash Focus: Vision Training in Minutes a Day', - platform: 'DS', - date: 1192395600000, - user_score: 3.8, - link: '/game/ds/flash-focus-vision-training-in-minutes-a-day', - esrb_rating: 'E', - developers: ['Nintendo', 'Namco Bandai Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 46, - title: 'Donkey Kong: Barrel Blast', - platform: 'WII', - date: 1191790800000, - user_score: 6.6, - link: '/game/wii/donkey-kong-barrel-blast', - esrb_rating: 'E', - developers: ['Paon Corporation'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Other', 'Kart'], - }, - { - meta_score: 90, - title: 'The Legend of Zelda: Phantom Hourglass', - platform: 'DS', - date: 1191186000000, - user_score: 7.9, - link: '/game/ds/the-legend-of-zelda-phantom-hourglass', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy', 'Fantasy', 'Open-World'], - }, - { - meta_score: null, - title: 'Super Mario Bros.: The Lost Levels', - platform: 'WII', - date: 1191186000000, - user_score: 5.8, - link: '/game/wii/super-mario-bros-the-lost-levels', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Sin and Punishment', - platform: 'WII', - date: 1191186000000, - user_score: 8.6, - link: '/game/wii/sin-and-punishment', - esrb_rating: 'T', - developers: ['Treasure'], - genres: ['Action', 'General'], - }, - { - meta_score: 78, - title: 'Chibi-Robo! Park Patrol', - platform: 'DS', - date: 1190581200000, - user_score: 7.7, - link: '/game/ds/chibi-robo!-park-patrol', - esrb_rating: 'E', - developers: ['Skip Ltd.'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: null, - title: "Kirby's Avalanche", - platform: 'WII', - date: 1190581200000, - user_score: 8.2, - link: '/game/wii/kirbys-avalanche', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: "Yoshi's Story", - platform: 'WII', - date: 1189976400000, - user_score: null, - link: '/game/wii/yoshis-story', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 77, - title: 'DK: Jungle Climber', - platform: 'DS', - date: 1189371600000, - user_score: 6.7, - link: '/game/ds/dk-jungle-climber', - esrb_rating: 'E', - developers: ['Paon Corporation'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'NES Play Action Football', - platform: 'WII', - date: 1189371600000, - user_score: null, - link: '/game/wii/nes-play-action-football', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Football', 'Sim'], - }, - { - meta_score: null, - title: 'Donkey Kong Jr. Math', - platform: 'WII', - date: 1188766800000, - user_score: 5, - link: '/game/wii/donkey-kong-jr-math', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment'], - }, - { - meta_score: 90, - title: 'Metroid Prime 3: Corruption', - platform: 'WII', - date: 1188162000000, - user_score: 8.8, - link: '/game/wii/metroid-prime-3-corruption', - esrb_rating: 'T', - developers: ['Retro Studios'], - genres: ['Action', 'Shooter', 'Shooter', 'First-Person', 'Sci-Fi', 'Sci-Fi', 'Arcade'], - }, - { - meta_score: 77, - title: 'Brain Age 2: More Training in Minutes a Day', - platform: 'DS', - date: 1187557200000, - user_score: 7.1, - link: '/game/ds/brain-age-2-more-training-in-minutes-a-day', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Super Metroid', - platform: 'WII', - date: 1187557200000, - user_score: 9.3, - link: '/game/wii/super-metroid', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Shining in the Darkness', - platform: 'WII', - date: 1186952400000, - user_score: null, - link: '/game/wii/shining-in-the-darkness', - esrb_rating: 'E', - developers: ['Climax Entertainment'], - genres: ['Role-Playing', 'First-Person'], - }, - { - meta_score: null, - title: 'Metroid', - platform: 'WII', - date: 1186952400000, - user_score: 7.4, - link: '/game/wii/metroid', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Wave Race 64', - platform: 'WII', - date: 1186347600000, - user_score: 8.3, - link: '/game/wii/wave-race-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Snow / Water'], - }, - { - meta_score: 79, - title: 'Mario Strikers Charged', - platform: 'WII', - date: 1185742800000, - user_score: 8.2, - link: '/game/wii/mario-strikers-charged', - esrb_rating: 'E10+', - developers: ['Next Level Games'], - genres: ['Sports', 'Traditional', 'Team', 'Soccer', 'Arcade', 'Arcade'], - }, - { - meta_score: 83, - title: 'Picross DS', - platform: 'DS', - date: 1185742800000, - user_score: 7.9, - link: '/game/ds/picross-ds', - esrb_rating: 'E', - developers: ['Jupiter Corporation'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Logic', 'Logic'], - }, - { - meta_score: null, - title: "Kirby's Dream Course", - platform: 'WII', - date: 1185138000000, - user_score: 8.9, - link: '/game/wii/kirbys-dream-course', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Golf', 'Arcade'], - }, - { - meta_score: null, - title: 'Paper Mario', - platform: 'WII', - date: 1184533200000, - user_score: 8.7, - link: '/game/wii/paper-mario', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: null, - title: 'Balloon Fight', - platform: 'WII', - date: 1184533200000, - user_score: 6.8, - link: '/game/wii/balloon-fight', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Yoshi', - platform: 'WII', - date: 1183928400000, - user_score: 8, - link: '/game/wii/yoshi', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Mach Rider', - platform: 'WII', - date: 1183928400000, - user_score: null, - link: '/game/wii/mach-rider', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Motorcycle', 'Street'], - }, - { - meta_score: null, - title: 'Super Mario Bros. 2', - platform: 'WII', - date: 1183323600000, - user_score: 7.9, - link: '/game/wii/super-mario-bros-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 53, - title: 'Pokemon Battle Revolution', - platform: 'WII', - date: 1182718800000, - user_score: 6.6, - link: '/game/wii/pokemon-battle-revolution', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Strategy', 'Turn-Based', 'Fantasy', 'General', 'Fantasy'], - }, - { - meta_score: null, - title: 'F-Zero X', - platform: 'WII', - date: 1182718800000, - user_score: 7.8, - link: '/game/wii/f-zero-x', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: null, - title: 'World Sports Competition', - platform: 'WII', - date: 1182114000000, - user_score: null, - link: '/game/wii/world-sports-competition', - esrb_rating: 'E', - developers: ['Hudson Soft'], - genres: ['Sports', 'General'], - }, - { - meta_score: null, - title: 'NES Open Tournament Golf', - platform: 'WII', - date: 1182114000000, - user_score: null, - link: '/game/wii/nes-open-tournament-golf', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Golf', 'Arcade'], - }, - { - meta_score: 68, - title: 'Big Brain Academy: Wii Degree', - platform: 'WII', - date: 1181509200000, - user_score: 7.1, - link: '/game/wii/big-brain-academy-wii-degree', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: null, - title: 'Nintendo DS Web Browser', - platform: 'DS', - date: 1180904400000, - user_score: 6.3, - link: '/game/ds/nintendo-ds-web-browser', - esrb_rating: '', - developers: ['Opera'], - genres: ['Miscellaneous', 'Web Browser', 'Application'], - }, - { - meta_score: null, - title: 'Zelda II: The Adventure of Link', - platform: 'WII', - date: 1180904400000, - user_score: 7.1, - link: '/game/wii/zelda-ii-the-adventure-of-link', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 86, - title: 'Planet Puzzle League', - platform: 'DS', - date: 1180904400000, - user_score: 7.9, - link: '/game/ds/planet-puzzle-league', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'ToeJam & Earl in Panic on Funkotron', - platform: 'WII', - date: 1180904400000, - user_score: 6.8, - link: '/game/wii/toejam-earl-in-panic-on-funkotron', - esrb_rating: 'E', - developers: ['ToeJam & Earl Productions'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 62, - title: 'Mario Party 8', - platform: 'WII', - date: 1180386000000, - user_score: 6.6, - link: '/game/wii/mario-party-8', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Kid Chameleon', - platform: 'WII', - date: 1180299600000, - user_score: null, - link: '/game/wii/kid-chameleon', - esrb_rating: 'E', - developers: ['Sega'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Streets of Rage 2', - platform: 'WII', - date: 1179694800000, - user_score: 8.1, - link: '/game/wii/streets-of-rage-2', - esrb_rating: 'E', - developers: ['Sega'], - genres: ['Action', "Beat-'Em-Up"], - }, - { - meta_score: null, - title: 'Blazing Lazers', - platform: 'WII', - date: 1179694800000, - user_score: 8.5, - link: '/game/wii/blazing-lazers', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Action', 'Shooter', 'Scrolling'], - }, - { - meta_score: null, - title: "Donkey Kong Country 2: Diddy's Kong Quest", - platform: 'WII', - date: 1179694800000, - user_score: 8.9, - link: '/game/wii/donkey-kong-country-2-diddys-kong-quest', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Ninja Spirit', - platform: 'WII', - date: 1179090000000, - user_score: null, - link: '/game/wii/ninja-spirit', - esrb_rating: 'E10+', - developers: ['Irem'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Mighty Bomb Jack', - platform: 'WII', - date: 1178485200000, - user_score: null, - link: '/game/wii/mighty-bomb-jack', - esrb_rating: 'E', - developers: ['Tecmo'], - genres: ['Action', 'General'], - }, - { - meta_score: null, - title: 'Final Fight', - platform: 'WII', - date: 1178485200000, - user_score: 8.5, - link: '/game/wii/final-fight', - esrb_rating: 'E', - developers: ['Capcom'], - genres: ['Action', "Beat-'Em-Up"], - }, - { - meta_score: null, - title: 'Ordyne', - platform: 'TG16)', - date: 1178485200000, - user_score: null, - link: '/game/wii/ordyne-tg16', - esrb_rating: 'E', - developers: ['Namco'], - genres: ['Action', 'Shooter', 'Scrolling'], - }, - { - meta_score: null, - title: 'Shockman', - platform: 'WII', - date: 1177880400000, - user_score: null, - link: '/game/wii/shockman', - esrb_rating: 'E', - developers: ['Winds'], - genres: ['Action', 'General', 'Platformer', '2D'], - }, - { - meta_score: 85, - title: 'Pokemon Diamond Version', - platform: 'DS', - date: 1177189200000, - user_score: 8.2, - link: '/game/ds/pokemon-diamond-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: 85, - title: 'Pokemon Pearl Version', - platform: 'DS', - date: 1177189200000, - user_score: 8.2, - link: '/game/ds/pokemon-pearl-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Trainer'], - }, - { - meta_score: null, - title: 'Punch-Out!! Featuring Mr. Dream', - platform: 'WII', - date: 1176670800000, - user_score: 8.6, - link: '/game/wii/punch-out!!-featuring-mr-dream', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Boxing'], - }, - { - meta_score: null, - title: 'Alex Kidd in the Enchanted Castle', - platform: 'WII', - date: 1176238800000, - user_score: null, - link: '/game/wii/alex-kidd-in-the-enchanted-castle', - esrb_rating: 'E', - developers: ['Sega'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 85, - title: 'Super Paper Mario', - platform: 'WII', - date: 1176066000000, - user_score: 8, - link: '/game/wii/super-paper-mario', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Action', 'Role-Playing', 'Platformer', 'Platformer', 'Action RPG', '3D', '3D'], - }, - { - meta_score: null, - title: 'Star Fox 64', - platform: 'WII', - date: 1175461200000, - user_score: 7.8, - link: '/game/wii/star-fox-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Rail'], - }, - { - meta_score: null, - title: 'Teenage Mutant Ninja Turtles', - platform: 'WII', - date: 1175461200000, - user_score: null, - link: '/game/wii/teenage-mutant-ninja-turtles', - esrb_rating: 'E10+', - developers: ['Magic Pockets'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '2D'], - }, - { - meta_score: null, - title: 'Romance of the Three Kingdoms IV: Wall of Fire', - platform: 'WII', - date: 1174856400000, - user_score: null, - link: '/game/wii/romance-of-the-three-kingdoms-iv-wall-of-fire', - esrb_rating: 'E', - developers: ['Koei'], - genres: ['Strategy', 'Turn-Based', 'Historic'], - }, - { - meta_score: 74, - title: 'Custom Robo Arena', - platform: 'DS', - date: 1174255200000, - user_score: 8.3, - link: '/game/ds/custom-robo-arena', - esrb_rating: 'E10+', - developers: ['Noise Inc.'], - genres: ['Action', 'Fighting', 'Fighting', '3D', '3D'], - }, - { - meta_score: null, - title: 'Excitebike', - platform: 'WII', - date: 1174255200000, - user_score: 7.3, - link: '/game/wii/excitebike', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Driving', 'General', 'Racing', 'Motorcycle', 'Motocross'], - }, - { - meta_score: 60, - title: 'Wario: Master of Disguise', - platform: 'DS', - date: 1173045600000, - user_score: 7.3, - link: '/game/ds/wario-master-of-disguise', - esrb_rating: 'E10+', - developers: ['Suzak'], - genres: ['Action', 'General', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: "Super Ghouls 'n Ghosts", - platform: 'WII', - date: 1173045600000, - user_score: 8, - link: '/game/wii/super-ghouls-n-ghosts', - esrb_rating: 'E', - developers: ['Capcom'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'The Legend of Zelda: Ocarina of Time', - platform: 'WII', - date: 1172440800000, - user_score: 8.5, - link: '/game/wii/the-legend-of-zelda-ocarina-of-time', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: null, - title: 'Chew-Man-Fu', - platform: 'WII', - date: 1172440800000, - user_score: null, - link: '/game/wii/chew-man-fu', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Donkey Kong Country', - platform: 'WII', - date: 1171836000000, - user_score: 8.5, - link: '/game/wii/donkey-kong-country', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Everybody Votes', - platform: 'WII', - date: 1171404000000, - user_score: null, - link: '/game/wii/everybody-votes', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: 58, - title: 'Wii Play', - platform: 'WII', - date: 1171231200000, - user_score: 6.6, - link: '/game/wii/wii-play', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Ice Climber', - platform: 'WII', - date: 1171231200000, - user_score: 6.3, - link: '/game/wii/ice-climber', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Kid Icarus', - platform: 'WII', - date: 1171231200000, - user_score: 7.9, - link: '/game/wii/kid-icarus', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: "Kirby's Adventure", - platform: 'WII', - date: 1171231200000, - user_score: 8.5, - link: '/game/wii/kirbys-adventure', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 63, - title: 'Diddy Kong Racing DS', - platform: 'DS', - date: 1170626400000, - user_score: 7, - link: '/game/ds/diddy-kong-racing-ds', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Other', 'Kart'], - }, - { - meta_score: null, - title: 'Super Mario World', - platform: 'WII', - date: 1170626400000, - user_score: 8.9, - link: '/game/wii/super-mario-world', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 92, - title: 'Final Fantasy VI Advance', - platform: 'GBA', - date: 1170626400000, - user_score: 8.7, - link: '/game/game-boy-advance/final-fantasy-vi-advance', - esrb_rating: 'E10+', - developers: ['TOSE'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: null, - title: 'Mario Kart 64', - platform: 'WII', - date: 1170021600000, - user_score: 7.3, - link: '/game/wii/mario-kart-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 78, - title: 'Hotel Dusk: Room 215', - platform: 'DS', - date: 1169416800000, - user_score: 8.6, - link: '/game/ds/hotel-dusk-room-215', - esrb_rating: 'T', - developers: ['Cing'], - genres: ['Adventure', 'General', 'General'], - }, - { - meta_score: null, - title: 'The Legend of Zelda: A Link to the Past', - platform: 'WII', - date: 1169416800000, - user_score: 8.8, - link: '/game/wii/the-legend-of-zelda-a-link-to-the-past', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 83, - title: 'WarioWare: Smooth Moves', - platform: 'WII', - date: 1168812000000, - user_score: 7.6, - link: '/game/wii/warioware-smooth-moves', - esrb_rating: 'E10+', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Party', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Urban Champion', - platform: 'WII', - date: 1167602400000, - user_score: null, - link: '/game/wii/urban-champion', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Fighting', '2D'], - }, - { - meta_score: null, - title: 'Baseball', - platform: 'WII', - date: 1167602400000, - user_score: null, - link: '/game/wii/baseball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Baseball', 'Arcade'], - }, - { - meta_score: null, - title: 'Super Mario Bros.', - platform: 'WII', - date: 1166997600000, - user_score: 8.4, - link: '/game/wii/super-mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Tennis', - platform: 'WII', - date: 1166392800000, - user_score: null, - link: '/game/wii/tennis', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Tennis'], - }, - { - meta_score: null, - title: 'Gunstar Heroes', - platform: 'WII', - date: 1165788000000, - user_score: 8.8, - link: '/game/wii/gunstar-heroes', - esrb_rating: 'E10+', - developers: ['Treasure'], - genres: ['Action', 'Shooter', 'Scrolling'], - }, - { - meta_score: null, - title: 'Ice Hockey', - platform: 'WII', - date: 1165788000000, - user_score: null, - link: '/game/wii/ice-hockey', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Ice Hockey', 'Arcade'], - }, - { - meta_score: 96, - title: 'The Legend of Zelda: Twilight Princess', - platform: 'GC', - date: 1165788000000, - user_score: 9, - link: '/game/gamecube/the-legend-of-zelda-twilight-princess', - esrb_rating: 'T', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: null, - title: 'Internet Channel', - platform: 'WII', - date: 1165528800000, - user_score: null, - link: '/game/wii/internet-channel', - esrb_rating: '', - developers: ['Opera'], - genres: ['Miscellaneous', 'Web Browser', 'Application'], - }, - { - meta_score: 71, - title: 'Kirby: Squeak Squad', - platform: 'DS', - date: 1165183200000, - user_score: 7.8, - link: '/game/ds/kirby-squeak-squad', - esrb_rating: 'E', - developers: ['Flagship', 'HAL Labs'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: null, - title: 'Donkey Kong Jr.', - platform: 'WII', - date: 1165183200000, - user_score: null, - link: '/game/wii/donkey-kong-jr', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 95, - title: 'The Legend of Zelda: Twilight Princess', - platform: 'WII', - date: 1163887200000, - user_score: 9, - link: '/game/wii/the-legend-of-zelda-twilight-princess', - esrb_rating: 'T', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy', 'General', 'Fantasy', 'Open-World'], - }, - { - meta_score: 72, - title: 'Excite Truck', - platform: 'WII', - date: 1163887200000, - user_score: 8.3, - link: '/game/wii/excite-truck', - esrb_rating: 'E', - developers: ['Monster Games Inc.'], - genres: ['Driving', 'Racing', 'Arcade', 'Arcade', 'Automobile'], - }, - { - meta_score: 76, - title: 'Wii Sports', - platform: 'WII', - date: 1163887200000, - user_score: 8.1, - link: '/game/wii/wii-sports', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'General', 'General', 'Individual', 'Athletics'], - }, - { - meta_score: null, - title: 'Wii Channels', - platform: 'WII', - date: 1163887200000, - user_score: 7.8, - link: '/game/wii/wii-channels', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Web Browser', 'Application'], - }, - { - meta_score: null, - title: 'F-Zero', - platform: 'WII', - date: 1163887200000, - user_score: 8.8, - link: '/game/wii/f-zero', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: null, - title: 'Super Mario 64', - platform: 'WII', - date: 1163887200000, - user_score: 8, - link: '/game/wii/super-mario-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: null, - title: 'SimCity', - platform: 'WII', - date: 1163887200000, - user_score: null, - link: '/game/wii/simcity', - esrb_rating: 'E', - developers: ['Maxis'], - genres: ['Strategy', 'City Building', 'Modern'], - }, - { - meta_score: null, - title: 'The Legend of Zelda', - platform: 'WII', - date: 1163887200000, - user_score: 8.2, - link: '/game/wii/the-legend-of-zelda', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: null, - title: 'Donkey Kong', - platform: 'WII', - date: 1163887200000, - user_score: 7.1, - link: '/game/wii/donkey-kong', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Mario Bros.', - platform: 'WII', - date: 1163887200000, - user_score: 6.6, - link: '/game/wii/mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: null, - title: 'Pinball', - platform: 'WII', - date: 1163887200000, - user_score: null, - link: '/game/wii/pinball', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Parlor', 'Pinball'], - }, - { - meta_score: null, - title: 'Soccer', - platform: 'WII', - date: 1163887200000, - user_score: null, - link: '/game/wii/soccer', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Traditional', 'Soccer', 'Sim'], - }, - { - meta_score: null, - title: "Wario's Woods", - platform: 'WII', - date: 1163887200000, - user_score: 7.6, - link: '/game/wii/warios-woods', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General'], - }, - { - meta_score: null, - title: 'Nintendo Wii', - platform: 'WII', - date: 1163887200000, - user_score: 8.1, - link: '/game/wii/nintendo-wii', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Hardware', 'Console'], - }, - { - meta_score: 81, - title: "Yoshi's Island DS", - platform: 'DS', - date: 1163368800000, - user_score: 8.1, - link: '/game/ds/yoshis-island-ds', - esrb_rating: 'E', - developers: ['Artoon'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 87, - title: 'Elite Beat Agents', - platform: 'DS', - date: 1162764000000, - user_score: 8.5, - link: '/game/ds/elite-beat-agents', - esrb_rating: 'E10+', - developers: ['iNiS'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: 83, - title: 'Final Fantasy V Advance', - platform: 'GBA', - date: 1162764000000, - user_score: 8.2, - link: '/game/game-boy-advance/final-fantasy-v-advance', - esrb_rating: 'E', - developers: ['TOSE'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 65, - title: 'Children of Mana', - platform: 'DS', - date: 1162332000000, - user_score: 6.4, - link: '/game/ds/children-of-mana', - esrb_rating: 'E10+', - developers: ['Nex Entertainment'], - genres: ['Role-Playing', 'Action RPG', 'Action RPG'], - }, - { - meta_score: 69, - title: 'Pokemon Ranger', - platform: 'DS', - date: 1162159200000, - user_score: 7.2, - link: '/game/ds/pokemon-ranger', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Role-Playing', 'Action RPG', 'Action RPG'], - }, - { - meta_score: 69, - title: 'Magical Starsign', - platform: 'DS', - date: 1161550800000, - user_score: 7.8, - link: '/game/ds/magical-starsign', - esrb_rating: 'E', - developers: ['Brownie Brown'], - genres: [ - 'Role-Playing', - 'General', - 'Console-style RPG', - 'Console-style RPG', - 'Japanese-Style', - ], - }, - { - meta_score: 83, - title: 'Nintendogs: Dalmatian & Friends', - platform: 'DS', - date: 1160946000000, - user_score: 7.4, - link: '/game/ds/nintendogs-dalmatian-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 83, - title: 'Clubhouse Games', - platform: 'DS', - date: 1160341200000, - user_score: 7.8, - link: '/game/ds/clubhouse-games', - esrb_rating: 'E', - developers: ['Agenda'], - genres: [ - 'Miscellaneous', - 'Board Games', - 'Board Games', - 'Board / Card Game', - 'Party / Minigame', - ], - }, - { - meta_score: 76, - title: 'Mario vs. Donkey Kong 2: March of the Minis', - platform: 'DS', - date: 1159131600000, - user_score: 7.8, - link: '/game/ds/mario-vs-donkey-kong-2-march-of-the-minis', - esrb_rating: 'E', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Puzzle', 'Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 75, - title: 'Baten Kaitos Origins', - platform: 'GC', - date: 1159131600000, - user_score: 8.3, - link: '/game/gamecube/baten-kaitos-origins', - esrb_rating: 'T', - developers: ['Monolith Soft', 'Namco Bandai Games'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 62, - title: 'Pokemon Mystery Dungeon: Blue Rescue Team', - platform: 'DS', - date: 1158526800000, - user_score: 8, - link: '/game/ds/pokemon-mystery-dungeon-blue-rescue-team', - esrb_rating: 'E', - developers: ['ChunSoft'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Roguelike'], - }, - { - meta_score: 67, - title: 'Pokemon Mystery Dungeon: Red Rescue Team', - platform: 'GBA', - date: 1158526800000, - user_score: 8.2, - link: '/game/game-boy-advance/pokemon-mystery-dungeon-red-rescue-team', - esrb_rating: 'E', - developers: ['ChunSoft'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 69, - title: 'Mario Hoops: 3 on 3', - platform: 'DS', - date: 1157922000000, - user_score: 7.8, - link: '/game/ds/mario-hoops-3-on-3', - esrb_rating: 'E', - developers: ['Square Enix'], - genres: ['Sports', 'Traditional', 'Team', 'Basketball', 'Arcade', 'Arcade'], - }, - { - meta_score: 76, - title: 'Star Fox Command', - platform: 'DS', - date: 1156712400000, - user_score: 6.8, - link: '/game/ds/star-fox-command', - esrb_rating: 'E10+', - developers: ['Q-Games'], - genres: [ - 'Action', - 'Simulation', - 'Shooter', - 'Flight', - 'Shooter', - 'Third-Person', - 'Combat', - 'Sci-Fi', - 'Sci-Fi', - 'Arcade', - ], - }, - { - meta_score: 37, - title: 'Tenchu: Dark Secret', - platform: 'DS', - date: 1156107600000, - user_score: 5.6, - link: '/game/ds/tenchu-dark-secret', - esrb_rating: 'T', - developers: ['From Software', 'Polygon Magic'], - genres: ['Action Adventure', 'Historic', 'General', 'Historic'], - }, - { - meta_score: 62, - title: 'Sudoku Gridmaster', - platform: 'DS', - date: 1151269200000, - user_score: 6, - link: '/game/ds/sudoku-gridmaster', - esrb_rating: 'E', - developers: ['AI'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Logic', 'Logic'], - }, - { - meta_score: 74, - title: 'Big Brain Academy', - platform: 'DS', - date: 1149454800000, - user_score: 7.4, - link: '/game/ds/big-brain-academy', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 68, - title: 'Magnetica', - platform: 'DS', - date: 1149454800000, - user_score: 7.7, - link: '/game/ds/magnetica', - esrb_rating: 'E', - developers: ['Mitchell'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'Matching', 'General'], - }, - { - meta_score: 89, - title: 'New Super Mario Bros.', - platform: 'DS', - date: 1147640400000, - user_score: 8.6, - link: '/game/ds/new-super-mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 77, - title: 'Brain Age: Train Your Brain in Minutes a Day!', - platform: 'DS', - date: 1145221200000, - user_score: 7.5, - link: '/game/ds/brain-age-train-your-brain-in-minutes-a-day!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 62, - title: 'Odama', - platform: 'GC', - date: 1144616400000, - user_score: 7.6, - link: '/game/gamecube/odama', - esrb_rating: 'E10+', - developers: ['Vivarium'], - genres: ['Miscellaneous', 'Parlor', 'Pinball'], - }, - { - meta_score: 85, - title: 'Metroid Prime: Hunters', - platform: 'DS', - date: 1142805600000, - user_score: 7.7, - link: '/game/ds/metroid-prime-hunters', - esrb_rating: 'T', - developers: ['Nintendo', 'Nintendo Software Technology'], - genres: ['Action', 'Shooter', 'Shooter', 'First-Person', 'Sci-Fi', 'Sci-Fi', 'Arcade'], - }, - { - meta_score: 84, - title: 'Tetris DS', - platform: 'DS', - date: 1142805600000, - user_score: 7.9, - link: '/game/ds/tetris-ds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Stacking', 'Stacking'], - }, - { - meta_score: 74, - title: 'Pokemon Trozei!', - platform: 'DS', - date: 1141596000000, - user_score: 7.2, - link: '/game/ds/pokemon-trozei!', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: 76, - title: 'Tales of Phantasia', - platform: 'GBA', - date: 1141596000000, - user_score: 8.1, - link: '/game/game-boy-advance/tales-of-phantasia', - esrb_rating: 'E10+', - developers: ['Namco'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 75, - title: 'Super Princess Peach', - platform: 'DS', - date: 1140991200000, - user_score: 8, - link: '/game/ds/super-princess-peach', - esrb_rating: 'E', - developers: ['TOSE'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 75, - title: 'Chibi-Robo!', - platform: 'GC', - date: 1139176800000, - user_score: 8.8, - link: '/game/gamecube/chibi-robo!', - esrb_rating: 'E10+', - developers: ['Skip Ltd.'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 81, - title: 'Drill Dozer', - platform: 'GBA', - date: 1139176800000, - user_score: 8.7, - link: '/game/game-boy-advance/drill-dozer', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 66, - title: 'True Swing Golf', - platform: 'DS', - date: 1137967200000, - user_score: 7.7, - link: '/game/ds/true-swing-golf', - esrb_rating: 'E', - developers: ['T&E Soft'], - genres: ['Sports', 'Traditional', 'Individual', 'Golf', 'Arcade', 'Arcade', 'Sim'], - }, - { - meta_score: 71, - title: 'Electroplankton', - platform: 'DS', - date: 1136757600000, - user_score: 7, - link: '/game/ds/electroplankton', - esrb_rating: 'E', - developers: ['indieszero'], - genres: [ - 'Action', - 'Miscellaneous', - 'Rhythm', - 'Music Maker', - 'Music Maker', - 'Application', - 'Music', - ], - }, - { - meta_score: 85, - title: 'Final Fantasy IV Advance', - platform: 'GBA', - date: 1134338400000, - user_score: 8.4, - link: '/game/game-boy-advance/final-fantasy-iv-advance', - esrb_rating: 'E10+', - developers: ['TOSE'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 86, - title: 'Animal Crossing: Wild World', - platform: 'DS', - date: 1133733600000, - user_score: 8.5, - link: '/game/ds/animal-crossing-wild-world', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual', 'Virtual Life'], - }, - { - meta_score: 76, - title: 'Super Mario Strikers', - platform: 'GC', - date: 1133733600000, - user_score: 8.6, - link: '/game/gamecube/super-mario-strikers', - esrb_rating: 'E', - developers: ['Next Level Games'], - genres: ['Sports', 'Traditional', 'Soccer', 'Arcade'], - }, - { - meta_score: 81, - title: 'Mario Tennis: Power Tour', - platform: 'GBA', - date: 1133733600000, - user_score: 8.6, - link: '/game/game-boy-advance/mario-tennis-power-tour', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Tennis'], - }, - { - meta_score: 86, - title: 'Mario & Luigi: Partners in Time', - platform: 'DS', - date: 1133128800000, - user_score: 8.5, - link: '/game/ds/mario-luigi-partners-in-time', - esrb_rating: 'E', - developers: ['Alphadream Corporation'], - genres: ['Role-Playing', 'Console-style RPG', 'Console-style RPG', 'Japanese-Style'], - }, - { - meta_score: 74, - title: 'Dr. Mario / Puzzle League', - platform: 'GBA', - date: 1133128800000, - user_score: 8, - link: '/game/game-boy-advance/dr-mario-puzzle-league', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Miscellaneous', 'Puzzle', 'Matching'], - }, - { - meta_score: 91, - title: 'Mario Kart DS', - platform: 'DS', - date: 1131919200000, - user_score: 8.7, - link: '/game/ds/mario-kart-ds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade', 'Kart', 'Kart', 'Automobile'], - }, - { - meta_score: 64, - title: 'Mario Party 7', - platform: 'GC', - date: 1131314400000, - user_score: 7.7, - link: '/game/gamecube/mario-party-7', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 77, - title: 'Donkey Kong Country 3', - platform: 'GBA', - date: 1131314400000, - user_score: 8.2, - link: '/game/game-boy-advance/donkey-kong-country-3', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 79, - title: 'Metroid Prime Pinball', - platform: 'DS', - date: 1130101200000, - user_score: 7.9, - link: '/game/ds/metroid-prime-pinball', - esrb_rating: 'E', - developers: ['Fuse Games Limited'], - genres: ['Action', 'Miscellaneous', 'Parlor', 'Pinball', 'Pinball'], - }, - { - meta_score: null, - title: 'Nintendogs: Best Friends', - platform: 'DS', - date: 1130101200000, - user_score: 7.3, - link: '/game/ds/nintendogs-best-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 69, - title: 'Dance Dance Revolution: Mario Mix', - platform: 'GC', - date: 1130101200000, - user_score: 8.1, - link: '/game/gamecube/dance-dance-revolution-mario-mix', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Rhythm', 'Dancing'], - }, - { - meta_score: 85, - title: 'Fire Emblem: Path of Radiance', - platform: 'GC', - date: 1129496400000, - user_score: 9.1, - link: '/game/gamecube/fire-emblem-path-of-radiance', - esrb_rating: 'T', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy'], - }, - { - meta_score: 64, - title: 'Pokemon XD: Gale of Darkness', - platform: 'GC', - date: 1127854800000, - user_score: 8.2, - link: '/game/gamecube/pokemon-xd-gale-of-darkness', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 70, - title: 'Trace Memory', - platform: 'DS', - date: 1127768400000, - user_score: 8.1, - link: '/game/ds/trace-memory', - esrb_rating: 'T', - developers: ['Cing'], - genres: ['Adventure', 'General', 'General', 'Point-and-Click'], - }, - { - meta_score: 76, - title: 'Battalion Wars', - platform: 'GC', - date: 1127077200000, - user_score: 8.4, - link: '/game/gamecube/battalion-wars', - esrb_rating: 'T', - developers: ['Kuju Entertainment'], - genres: ['Action', 'Shooter', 'Third-Person', 'Modern'], - }, - { - meta_score: 70, - title: 'DK: King of Swing', - platform: 'GBA', - date: 1127077200000, - user_score: 5.7, - link: '/game/game-boy-advance/dk-king-of-swing', - esrb_rating: 'E', - developers: ['Paon Corporation'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 76, - title: 'Mario Superstar Baseball', - platform: 'GC', - date: 1125262800000, - user_score: 8.4, - link: '/game/gamecube/mario-superstar-baseball', - esrb_rating: 'E', - developers: ['Namco'], - genres: ['Sports', 'Traditional', 'Baseball', 'Arcade'], - }, - { - meta_score: 56, - title: 'Dynasty Warriors Advance', - platform: 'GBA', - date: 1125262800000, - user_score: 7.6, - link: '/game/game-boy-advance/dynasty-warriors-advance', - esrb_rating: 'E', - developers: ['Koei'], - genres: ['Action', "Beat-'Em-Up"], - }, - { - meta_score: 90, - title: 'Advance Wars: Dual Strike', - platform: 'DS', - date: 1124658000000, - user_score: 8.8, - link: '/game/ds/advance-wars-dual-strike', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Modern', 'Modern', 'Tactics'], - }, - { - meta_score: 83, - title: 'Nintendogs: Chihuahua & Friends', - platform: 'DS', - date: 1124658000000, - user_score: 7.8, - link: '/game/ds/nintendogs-chihuahua-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 83, - title: 'Nintendogs: Dachshund & Friends', - platform: 'DS', - date: 1124658000000, - user_score: 7.9, - link: '/game/ds/nintendogs-dachshund-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 83, - title: 'Nintendogs: Lab & Friends', - platform: 'DS', - date: 1124658000000, - user_score: 7.6, - link: '/game/ds/nintendogs-lab-friends', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Simulation', 'Miscellaneous', 'Virtual Life', 'Virtual Life', 'Virtual', 'Pet'], - }, - { - meta_score: 66, - title: 'Geist', - platform: 'GC', - date: 1124053200000, - user_score: 8, - link: '/game/gamecube/geist', - esrb_rating: 'M', - developers: ['n-Space'], - genres: ['Action', 'Shooter', 'First-Person', 'Sci-Fi'], - }, - { - meta_score: 88, - title: 'Meteos', - platform: 'DS', - date: 1119906000000, - user_score: 7.4, - link: '/game/ds/meteos', - esrb_rating: 'E', - developers: ['Q Entertainment'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Puzzle', 'Matching', 'Matching'], - }, - { - meta_score: 86, - title: 'Kirby: Canvas Curse', - platform: 'DS', - date: 1118610000000, - user_score: 7.8, - link: '/game/ds/kirby-canvas-curse', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 60, - title: 'Yoshi Topsy-Turvy', - platform: 'GBA', - date: 1118610000000, - user_score: 7.1, - link: '/game/game-boy-advance/yoshi-topsy-turvy', - esrb_rating: 'E', - developers: ['Artoon'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 85, - title: 'Fire Emblem: The Sacred Stones', - platform: 'GBA', - date: 1116795600000, - user_score: 9, - link: '/game/game-boy-advance/fire-emblem-the-sacred-stones', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy'], - }, - { - meta_score: 88, - title: 'WarioWare: Twisted!', - platform: 'GBA', - date: 1116795600000, - user_score: 8.7, - link: '/game/game-boy-advance/warioware-twisted!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 69, - title: 'Donkey Konga 2', - platform: 'GC', - date: 1115586000000, - user_score: 7, - link: '/game/gamecube/donkey-konga-2', - esrb_rating: 'T', - developers: ['Namco'], - genres: ['Miscellaneous', 'Rhythm', 'Music'], - }, - { - meta_score: 76, - title: 'Pokemon Emerald Version', - platform: 'GBA', - date: 1114808400000, - user_score: 8.9, - link: '/game/game-boy-advance/pokemon-emerald-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 73, - title: 'Polarium', - platform: 'DS', - date: 1113771600000, - user_score: 8.2, - link: '/game/ds/polarium', - esrb_rating: 'E', - developers: ['Mitchell'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'General', 'Puzzle', 'Stacking', 'General'], - }, - { - meta_score: 54, - title: 'Mario Party Advance', - platform: 'GBA', - date: 1111957200000, - user_score: 4.8, - link: '/game/game-boy-advance/mario-party-advance', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 73, - title: 'Yoshi Touch & Go', - platform: 'DS', - date: 1110751200000, - user_score: 6.8, - link: '/game/ds/yoshi-touch-go', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '2D', '2D'], - }, - { - meta_score: 46, - title: 'Pokemon Dash', - platform: 'DS', - date: 1110751200000, - user_score: 5.3, - link: '/game/ds/pokemon-dash', - esrb_rating: 'E', - developers: ['Ambrella'], - genres: ['Driving', 'Racing', 'Arcade', 'On-foot', 'Other', 'On-foot'], - }, - { - meta_score: 80, - title: 'Donkey Kong Jungle Beat', - platform: 'GC', - date: 1110751200000, - user_score: 8.3, - link: '/game/gamecube/donkey-kong-jungle-beat', - esrb_rating: 'E10+', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 81, - title: 'WarioWare: Touched!', - platform: 'DS', - date: 1108332000000, - user_score: 8.2, - link: '/game/ds/warioware-touched!', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: [ - 'Miscellaneous', - 'Puzzle', - 'Puzzle', - 'General', - 'Puzzle', - 'Party / Minigame', - 'General', - ], - }, - { - meta_score: 67, - title: 'Star Fox: Assault', - platform: 'GC', - date: 1108332000000, - user_score: 8.2, - link: '/game/gamecube/star-fox-assault', - esrb_rating: 'T', - developers: ['Namco'], - genres: ['Action', 'Shooter', 'Third-Person', 'Sci-Fi'], - }, - { - meta_score: 89, - title: 'The Legend of Zelda: The Minish Cap', - platform: 'GBA', - date: 1105308000000, - user_score: 8.9, - link: '/game/game-boy-advance/the-legend-of-zelda-the-minish-cap', - esrb_rating: 'E', - developers: ['Flagship'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 71, - title: 'Mario Party 6', - platform: 'GC', - date: 1102284000000, - user_score: 7.9, - link: '/game/gamecube/mario-party-6', - esrb_rating: 'E', - developers: ['Hudson Soft'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 79, - title: 'Final Fantasy I & II: Dawn of Souls', - platform: 'GBA', - date: 1101679200000, - user_score: 8, - link: '/game/game-boy-advance/final-fantasy-i-ii-dawn-of-souls', - esrb_rating: 'E', - developers: ['Tose Software'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: null, - title: 'PictoChat', - platform: 'DS', - date: 1100988000000, - user_score: 7.5, - link: '/game/ds/pictochat', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'Application'], - }, - { - meta_score: 85, - title: 'Super Mario 64 DS', - platform: 'DS', - date: 1100901600000, - user_score: 8.3, - link: '/game/ds/super-mario-64-ds', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', 'Platformer', '3D', '3D'], - }, - { - meta_score: null, - title: 'Nintendo DS', - platform: 'DS', - date: 1100901600000, - user_score: 8.2, - link: '/game/ds/nintendo-ds', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Hardware', 'Console'], - }, - { - meta_score: null, - title: 'Metroid Prime: Hunters - First Hunt', - platform: 'DS', - date: 1100901600000, - user_score: null, - link: '/game/ds/metroid-prime-hunters---first-hunt', - esrb_rating: 'RP', - developers: ['Nintendo Software Technology'], - genres: ['Action', 'Shooter', 'First-Person', 'Arcade'], - }, - { - meta_score: 92, - title: 'Metroid Prime 2: Echoes', - platform: 'GC', - date: 1100469600000, - user_score: 8.9, - link: '/game/gamecube/metroid-prime-2-echoes', - esrb_rating: 'T', - developers: ['Retro Studios'], - genres: ['Action', 'Shooter', 'First-Person', 'Sci-Fi'], - }, - { - meta_score: 80, - title: 'Donkey Kong Country 2', - platform: 'GBA', - date: 1100469600000, - user_score: 8.6, - link: '/game/game-boy-advance/donkey-kong-country-2', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 80, - title: 'Mario Power Tennis', - platform: 'GC', - date: 1099864800000, - user_score: 8.5, - link: '/game/gamecube/mario-power-tennis', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Tennis'], - }, - { - meta_score: 66, - title: 'Classic NES Series: Dr. Mario', - platform: 'GBA', - date: 1098651600000, - user_score: 8.2, - link: '/game/game-boy-advance/classic-nes-series-dr-mario', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Matching'], - }, - { - meta_score: 74, - title: 'Classic NES Series: Castlevania', - platform: 'GBA', - date: 1098651600000, - user_score: 8.6, - link: '/game/game-boy-advance/classic-nes-series-castlevania', - esrb_rating: 'E', - developers: ['Konami'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 73, - title: 'Classic NES Series: Zelda II: The Adventure of Link', - platform: 'GBA', - date: 1098651600000, - user_score: 7, - link: '/game/game-boy-advance/classic-nes-series-zelda-ii-the-adventure-of-link', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 58, - title: 'Classic NES Series: Metroid', - platform: 'GBA', - date: 1098651600000, - user_score: 8.2, - link: '/game/game-boy-advance/classic-nes-series-metroid', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Sci-Fi'], - }, - { - meta_score: 80, - title: 'Kirby & the Amazing Mirror', - platform: 'GBA', - date: 1098046800000, - user_score: 8.6, - link: '/game/game-boy-advance/kirby-the-amazing-mirror', - esrb_rating: 'E', - developers: ['Flagship'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 87, - title: 'Paper Mario: The Thousand-Year Door', - platform: 'GC', - date: 1097442000000, - user_score: 9.1, - link: '/game/gamecube/paper-mario-the-thousand-year-door', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 62, - title: 'Mario Pinball Land', - platform: 'GBA', - date: 1096837200000, - user_score: 4.2, - link: '/game/game-boy-advance/mario-pinball-land', - esrb_rating: 'E', - developers: ['Fuse Games Limited'], - genres: ['Miscellaneous', 'Parlor', 'Pinball'], - }, - { - meta_score: 76, - title: 'Donkey Konga', - platform: 'GC', - date: 1096232400000, - user_score: 7.9, - link: '/game/gamecube/donkey-konga', - esrb_rating: 'E', - developers: ['Namco'], - genres: ['Miscellaneous', 'Rhythm', 'Music'], - }, - { - meta_score: 77, - title: 'F-Zero GP Legend', - platform: 'GBA', - date: 1095627600000, - user_score: 8.3, - link: '/game/game-boy-advance/f-zero-gp-legend', - esrb_rating: 'E', - developers: ['Suzak'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: 81, - title: 'Pokemon FireRed Version', - platform: 'GBA', - date: 1094504400000, - user_score: 8.6, - link: '/game/game-boy-advance/pokemon-firered-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 81, - title: 'Pokemon LeafGreen Version', - platform: 'GBA', - date: 1094504400000, - user_score: 8.5, - link: '/game/game-boy-advance/pokemon-leafgreen-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 90, - title: 'Pikmin 2', - platform: 'GC', - date: 1093813200000, - user_score: 9.1, - link: '/game/gamecube/pikmin-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'Fantasy'], - }, - { - meta_score: 77, - title: 'Hamtaro: Ham-Ham Games', - platform: 'GBA', - date: 1090875600000, - user_score: 8.3, - link: '/game/game-boy-advance/hamtaro-ham-ham-games', - esrb_rating: 'E', - developers: ['Alphadream Corporation'], - genres: ['Sports', 'General'], - }, - { - meta_score: null, - title: 'Pokemon Box: Ruby and Sapphire', - platform: 'GC', - date: 1089579600000, - user_score: 5, - link: '/game/gamecube/pokemon-box-ruby-and-sapphire', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General'], - }, - { - meta_score: 84, - title: 'Mario Golf: Advance Tour', - platform: 'GBA', - date: 1087851600000, - user_score: 8.5, - link: '/game/game-boy-advance/mario-golf-advance-tour', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Golf', 'Sim'], - }, - { - meta_score: 86, - title: 'The Legend of Zelda: Four Swords Adventures', - platform: 'GC', - date: 1086555600000, - user_score: 7.6, - link: '/game/gamecube/the-legend-of-zelda-four-swords-adventures', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 66, - title: 'Classic NES Series: Ice Climber', - platform: 'GBA', - date: 1086123600000, - user_score: 7.8, - link: '/game/game-boy-advance/classic-nes-series-ice-climber', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 66, - title: 'Classic NES Series: Excitebike', - platform: 'GBA', - date: 1086123600000, - user_score: 7.8, - link: '/game/game-boy-advance/classic-nes-series-excitebike', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade'], - }, - { - meta_score: 84, - title: 'Classic NES Series: Super Mario Bros.', - platform: 'GBA', - date: 1086123600000, - user_score: 8.4, - link: '/game/game-boy-advance/classic-nes-series-super-mario-bros', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 84, - title: 'Classic NES Series: The Legend of Zelda', - platform: 'GBA', - date: 1086123600000, - user_score: 8.4, - link: '/game/game-boy-advance/classic-nes-series-the-legend-of-zelda', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 55, - title: 'Classic NES Series: Donkey Kong', - platform: 'GBA', - date: 1086123600000, - user_score: 6.1, - link: '/game/game-boy-advance/classic-nes-series-donkey-kong', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 53, - title: 'Classic NES Series: Pac-Man', - platform: 'GBA', - date: 1086123600000, - user_score: 7.8, - link: '/game/game-boy-advance/classic-nes-series-pac-man', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 81, - title: 'Mario vs. Donkey Kong', - platform: 'GBA', - date: 1085346000000, - user_score: 8.2, - link: '/game/game-boy-advance/mario-vs-donkey-kong', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 65, - title: 'Custom Robo', - platform: 'GC', - date: 1084136400000, - user_score: 8.1, - link: '/game/gamecube/custom-robo', - esrb_rating: 'T', - developers: ['Noise Inc.'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 76, - title: 'WarioWare, Inc.: Mega Party Game$!', - platform: 'GC', - date: 1081198800000, - user_score: 8, - link: '/game/gamecube/warioware-inc-mega-party-game!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 73, - title: 'Pokemon Colosseum', - platform: 'GC', - date: 1079906400000, - user_score: 8, - link: '/game/gamecube/pokemon-colosseum', - esrb_rating: 'E', - developers: ['Genius Sonority Inc.'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 80, - title: 'Final Fantasy Crystal Chronicles', - platform: 'GC', - date: 1076277600000, - user_score: 8.9, - link: '/game/gamecube/final-fantasy-crystal-chronicles', - esrb_rating: 'T', - developers: ['Square Enix'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 89, - title: 'Metroid: Zero Mission', - platform: 'GBA', - date: 1076277600000, - user_score: 9.1, - link: '/game/game-boy-advance/metroid-zero-mission', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 78, - title: 'Pac-Man vs.', - platform: 'GC', - date: 1070316000000, - user_score: 8.3, - link: '/game/gamecube/pac-man-vs', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 73, - title: '1080: Avalanche', - platform: 'GC', - date: 1070229600000, - user_score: 7.8, - link: '/game/gamecube/1080-avalanche', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Sports', 'Alternative', 'Snowboarding'], - }, - { - meta_score: 72, - title: 'Sword of Mana', - platform: 'GBA', - date: 1070229600000, - user_score: 8.5, - link: '/game/game-boy-advance/sword-of-mana', - esrb_rating: 'E', - developers: ['Brownie Brown'], - genres: ['Role-Playing', 'Action RPG'], - }, - { - meta_score: 55, - title: 'Pokemon Channel', - platform: 'GC', - date: 1070229600000, - user_score: 6.4, - link: '/game/gamecube/pokemon-channel', - esrb_rating: 'E', - developers: ['Ambrella'], - genres: ['Adventure', 'First-Person', 'Fantasy'], - }, - { - meta_score: 87, - title: 'Mario Kart: Double Dash!!', - platform: 'GC', - date: 1069020000000, - user_score: 8.6, - link: '/game/gamecube/mario-kart-double-dash!!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 90, - title: 'Mario & Luigi: Superstar Saga', - platform: 'GBA', - date: 1069020000000, - user_score: 8.8, - link: '/game/game-boy-advance/mario-luigi-superstar-saga', - esrb_rating: 'E', - developers: ['Alphadream Corporation'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 95, - title: "The Legend of Zelda Collector's Edition", - platform: 'GC', - date: 1069020000000, - user_score: 8.9, - link: '/game/gamecube/the-legend-of-zelda-collectors-edition', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 69, - title: 'Mario Party 5', - platform: 'GC', - date: 1068415200000, - user_score: 7.7, - link: '/game/gamecube/mario-party-5', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 88, - title: 'Fire Emblem', - platform: 'GBA', - date: 1067810400000, - user_score: 9.1, - link: '/game/game-boy-advance/fire-emblem', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Fantasy'], - }, - { - meta_score: 78, - title: 'Top Gear Rally', - platform: 'GBA', - date: 1067292000000, - user_score: 7.5, - link: '/game/game-boy-advance/top-gear-rally', - esrb_rating: 'E', - developers: ['Tantalus'], - genres: ['Driving', 'Racing', 'Rally / Offroad'], - }, - { - meta_score: 94, - title: 'Super Mario Advance 4: Super Mario Bros. 3', - platform: 'GBA', - date: 1066683600000, - user_score: 9.1, - link: '/game/game-boy-advance/super-mario-advance-4-super-mario-bros-3', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 61, - title: 'Kirby Air Ride', - platform: 'GC', - date: 1065992400000, - user_score: 8.2, - link: '/game/gamecube/kirby-air-ride', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 87, - title: 'Final Fantasy Tactics Advance', - platform: 'GBA', - date: 1062968400000, - user_score: 9, - link: '/game/game-boy-advance/final-fantasy-tactics-advance', - esrb_rating: 'E', - developers: ['Square Enix'], - genres: ['Strategy', 'Turn-Based', 'Fantasy'], - }, - { - meta_score: 89, - title: 'F-Zero GX', - platform: 'GC', - date: 1061845200000, - user_score: 8.6, - link: '/game/gamecube/f-zero-gx', - esrb_rating: 'T', - developers: ['Amusement Vision'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: 81, - title: 'Pokemon Pinball: Ruby & Sapphire', - platform: 'GBA', - date: 1061845200000, - user_score: 7.7, - link: '/game/game-boy-advance/pokemon-pinball-ruby-sapphire', - esrb_rating: 'E', - developers: ['Jupiter Corporation'], - genres: ['Miscellaneous', 'Parlor', 'Pinball'], - }, - { - meta_score: 81, - title: 'Mario Golf: Toadstool Tour', - platform: 'GC', - date: 1059426000000, - user_score: 8.1, - link: '/game/gamecube/mario-golf-toadstool-tour', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Golf', 'Arcade'], - }, - { - meta_score: 71, - title: 'Wario World', - platform: 'GC', - date: 1056402000000, - user_score: 7.6, - link: '/game/gamecube/wario-world', - esrb_rating: 'E', - developers: ['Treasure'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 89, - title: 'Advance Wars 2: Black Hole Rising', - platform: 'GBA', - date: 1056402000000, - user_score: 8.8, - link: '/game/game-boy-advance/advance-wars-2-black-hole-rising', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Sci-Fi'], - }, - { - meta_score: 78, - title: 'Donkey Kong Country', - platform: 'GBA', - date: 1055106000000, - user_score: 8.7, - link: '/game/game-boy-advance/donkey-kong-country', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 89, - title: 'WarioWare, Inc.: Mega Microgame$!', - platform: 'GBA', - date: 1053464400000, - user_score: 8.6, - link: '/game/game-boy-advance/warioware-inc-mega-microgame!', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 86, - title: 'Golden Sun: The Lost Age', - platform: 'GBA', - date: 1050267600000, - user_score: 9, - link: '/game/game-boy-advance/golden-sun-the-lost-age', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 72, - title: 'Hamtaro: Ham Ham Heartbreak', - platform: 'GBA', - date: 1049749200000, - user_score: 8.4, - link: '/game/game-boy-advance/hamtaro-ham-ham-heartbreak', - esrb_rating: 'E', - developers: ['Pax Softonica'], - genres: ['Action', 'General'], - }, - { - meta_score: 96, - title: 'The Legend of Zelda: The Wind Waker', - platform: 'GC', - date: 1048456800000, - user_score: 9, - link: '/game/gamecube/the-legend-of-zelda-the-wind-waker', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 82, - title: 'Pokemon Ruby Version', - platform: 'GBA', - date: 1047938400000, - user_score: 8.5, - link: '/game/game-boy-advance/pokemon-ruby-version', - esrb_rating: 'E', - developers: ['Game Freak'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 91, - title: 'The Legend of Zelda: Ocarina of Time / Master Quest', - platform: 'GC', - date: 1046383200000, - user_score: 8.9, - link: '/game/gamecube/the-legend-of-zelda-ocarina-of-time-master-quest', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 95, - title: 'The Legend of Zelda: A Link to the Past', - platform: 'GBA', - date: 1038866400000, - user_score: 9, - link: '/game/game-boy-advance/the-legend-of-zelda-a-link-to-the-past', - esrb_rating: 'E', - developers: ['Capcom'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 81, - title: 'Kirby: Nightmare in Dream Land', - platform: 'GBA', - date: 1038780000000, - user_score: 8.6, - link: '/game/game-boy-advance/kirby-nightmare-in-dream-land', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 97, - title: 'Metroid Prime', - platform: 'GC', - date: 1037484000000, - user_score: 9, - link: '/game/gamecube/metroid-prime', - esrb_rating: 'T', - developers: ['Retro Studios'], - genres: ['Action', 'Shooter', 'First-Person', 'Sci-Fi'], - }, - { - meta_score: 92, - title: 'Metroid Fusion', - platform: 'GBA', - date: 1037484000000, - user_score: 9, - link: '/game/game-boy-advance/metroid-fusion', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Sci-Fi'], - }, - { - meta_score: 71, - title: 'Cubivore: Survival of the Fittest', - platform: 'GC', - date: 1036447200000, - user_score: 8.1, - link: '/game/gamecube/cubivore-survival-of-the-fittest', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'General'], - }, - { - meta_score: 71, - title: 'Game & Watch Gallery 4', - platform: 'GBA', - date: 1035756000000, - user_score: 8.1, - link: '/game/game-boy-advance/game-watch-gallery-4', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Compilation'], - }, - { - meta_score: 70, - title: 'Mario Party 4', - platform: 'GC', - date: 1035147600000, - user_score: 7.7, - link: '/game/gamecube/mario-party-4', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 91, - title: "Yoshi's Island: Super Mario Advance 3", - platform: 'GBA', - date: 1032814800000, - user_score: 9.1, - link: '/game/game-boy-advance/yoshis-island-super-mario-advance-3', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 82, - title: 'Star Fox Adventures', - platform: 'GC', - date: 1032642000000, - user_score: 8, - link: '/game/gamecube/star-fox-adventures', - esrb_rating: 'T', - developers: ['Rare Ltd.'], - genres: ['Action Adventure', 'Sci-Fi'], - }, - { - meta_score: 87, - title: 'Animal Crossing', - platform: 'GC', - date: 1032037200000, - user_score: 8.8, - link: '/game/gamecube/animal-crossing', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Virtual Life'], - }, - { - meta_score: 92, - title: 'Super Mario Sunshine', - platform: 'GC', - date: 1030222800000, - user_score: 8.3, - link: '/game/gamecube/super-mario-sunshine', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 50, - title: "Disney's Magical Mirror Starring Mickey Mouse", - platform: 'GC', - date: 1029186000000, - user_score: 7.6, - link: '/game/gamecube/disneys-magical-mirror-starring-mickey-mouse', - esrb_rating: 'E', - developers: ['Capcom'], - genres: ['Adventure', 'Third-Person', 'Fantasy'], - }, - { - meta_score: 70, - title: "Disney's Magical Quest", - platform: 'GBA', - date: 1029186000000, - user_score: null, - link: '/game/game-boy-advance/disneys-magical-quest', - esrb_rating: 'E', - developers: ['Sun-Tec'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 92, - title: "Eternal Darkness: Sanity's Requiem", - platform: 'GC', - date: 1024779600000, - user_score: 8.8, - link: '/game/gamecube/eternal-darkness-sanitys-requiem', - esrb_rating: 'M', - developers: ['Silicon Knights'], - genres: ['Action Adventure', 'Horror'], - }, - { - meta_score: 92, - title: 'Super Mario World: Super Mario Advance 2', - platform: 'GBA', - date: 1013205600000, - user_score: 9.1, - link: '/game/game-boy-advance/super-mario-world-super-mario-advance-2', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 71, - title: 'NBA Courtside 2002', - platform: 'GC', - date: 1010872800000, - user_score: 7.4, - link: '/game/gamecube/nba-courtside-2002', - esrb_rating: 'E', - developers: ['Left Field Productions'], - genres: ['Sports', 'Traditional', 'Basketball', 'Sim'], - }, - { - meta_score: 92, - title: 'Super Smash Bros. Melee', - platform: 'GC', - date: 1007244000000, - user_score: 9, - link: '/game/gamecube/super-smash-bros-melee', - esrb_rating: 'T', - developers: ['HAL Labs'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 89, - title: 'Pikmin', - platform: 'GC', - date: 1007244000000, - user_score: 8.7, - link: '/game/gamecube/pikmin', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Strategy', 'Real-Time', 'Fantasy'], - }, - { - meta_score: 88, - title: 'Wario Land 4', - platform: 'GBA', - date: 1006034400000, - user_score: 8.8, - link: '/game/game-boy-advance/wario-land-4', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 80, - title: 'Wave Race: Blue Storm', - platform: 'GC', - date: 1005948000000, - user_score: 8, - link: '/game/gamecube/wave-race-blue-storm', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Snow / Water'], - }, - { - meta_score: 78, - title: "Luigi's Mansion", - platform: 'GC', - date: 1005948000000, - user_score: 8.6, - link: '/game/gamecube/luigis-mansion', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 91, - title: 'Golden Sun', - platform: 'GBA', - date: 1005429600000, - user_score: 9, - link: '/game/game-boy-advance/golden-sun', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 92, - title: 'Advance Wars', - platform: 'GBA', - date: 999982800000, - user_score: 8.8, - link: '/game/game-boy-advance/advance-wars', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Strategy', 'Turn-Based', 'Modern'], - }, - { - meta_score: 93, - title: 'Mario Kart Super Circuit', - platform: 'GBA', - date: 998773200000, - user_score: 8, - link: '/game/game-boy-advance/mario-kart-super-circuit', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 86, - title: 'F-Zero: Maximum Velocity', - platform: 'GBA', - date: 992293200000, - user_score: 7.8, - link: '/game/game-boy-advance/f-zero-maximum-velocity', - esrb_rating: 'E', - developers: ['Nd Cube'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: 84, - title: 'Super Mario Advance', - platform: 'GBA', - date: 992120400000, - user_score: 8.2, - link: '/game/game-boy-advance/super-mario-advance', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 74, - title: 'Mario Party 3', - platform: 'N64', - date: 989096400000, - user_score: 8.2, - link: '/game/nintendo-64/mario-party-3', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 71, - title: 'Dr. Mario 64', - platform: 'N64', - date: 986677200000, - user_score: 7.3, - link: '/game/nintendo-64/dr-mario-64', - esrb_rating: 'E', - developers: ['Newcom'], - genres: ['Miscellaneous', 'Puzzle', 'Matching'], - }, - { - meta_score: 78, - title: 'Pokemon Stadium 2', - platform: 'N64', - date: 985726800000, - user_score: 8.4, - link: '/game/nintendo-64/pokemon-stadium-2', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Strategy', 'General'], - }, - { - meta_score: 93, - title: 'Paper Mario', - platform: 'N64', - date: 981324000000, - user_score: 9, - link: '/game/nintendo-64/paper-mario', - esrb_rating: 'E', - developers: ['Intelligent Systems'], - genres: ['Role-Playing', 'Console-style RPG'], - }, - { - meta_score: 90, - title: 'Banjo-Tooie', - platform: 'N64', - date: 974584800000, - user_score: 8.8, - link: '/game/nintendo-64/banjo-tooie', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 71, - title: "Mickey's Speedway USA", - platform: 'N64', - date: 974066400000, - user_score: 7.7, - link: '/game/nintendo-64/mickeys-speedway-usa', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 57, - title: 'Hey You, Pikachu!', - platform: 'N64', - date: 973375200000, - user_score: 6.3, - link: '/game/nintendo-64/hey-you-pikachu!', - esrb_rating: 'E', - developers: ['Ambrella'], - genres: ['Adventure', 'General'], - }, - { - meta_score: 95, - title: "The Legend of Zelda: Majora's Mask", - platform: 'N64', - date: 972424800000, - user_score: 9.1, - link: '/game/nintendo-64/the-legend-of-zelda-majoras-mask', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 81, - title: 'Pokemon Puzzle League', - platform: 'N64', - date: 967759200000, - user_score: 8.4, - link: '/game/nintendo-64/pokemon-puzzle-league', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Puzzle', 'Matching'], - }, - { - meta_score: 91, - title: 'Mario Tennis', - platform: 'N64', - date: 967413600000, - user_score: 8.7, - link: '/game/nintendo-64/mario-tennis', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Tennis'], - }, - { - meta_score: 77, - title: 'Kirby 64: The Crystal Shards', - platform: 'N64', - date: 961970400000, - user_score: 8.1, - link: '/game/nintendo-64/kirby-64-the-crystal-shards', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 80, - title: 'Starcraft 64', - platform: 'N64', - date: 960847200000, - user_score: 7.6, - link: '/game/nintendo-64/starcraft-64', - esrb_rating: 'T', - developers: ['Mass Media'], - genres: ['Strategy', 'Real-Time', 'Sci-Fi'], - }, - { - meta_score: 97, - title: 'Perfect Dark', - platform: 'N64', - date: 958946400000, - user_score: 8.8, - link: '/game/nintendo-64/perfect-dark', - esrb_rating: 'M', - developers: ['Rare Ltd.'], - genres: ['Action', 'Shooter', 'First-Person', 'Sci-Fi'], - }, - { - meta_score: 88, - title: 'Excitebike 64', - platform: 'N64', - date: 957045600000, - user_score: 8.2, - link: '/game/nintendo-64/excitebike-64', - esrb_rating: 'E', - developers: ['Left Field Productions'], - genres: ['Driving', 'Racing', 'Motorcycle', 'Motocross'], - }, - { - meta_score: 82, - title: 'Ridge Racer 64', - platform: 'N64', - date: 950479200000, - user_score: 8.1, - link: '/game/nintendo-64/ridge-racer-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Arcade'], - }, - { - meta_score: 91, - title: 'Mario Golf', - platform: 'N64', - date: 930690000000, - user_score: 7.8, - link: '/game/nintendo-64/mario-golf', - esrb_rating: 'E', - developers: ['Camelot Software Planning'], - genres: ['Sports', 'Traditional', 'Golf', 'Arcade'], - }, - { - meta_score: 77, - title: 'Pokemon Snap', - platform: 'N64', - date: 930690000000, - user_score: 7.7, - link: '/game/nintendo-64/pokemon-snap', - esrb_rating: 'E', - developers: ['Hal'], - genres: ['Action', 'General'], - }, - { - meta_score: 79, - title: 'Super Smash Bros.', - platform: 'N64', - date: 925074000000, - user_score: 8.6, - link: '/game/nintendo-64/super-smash-bros', - esrb_rating: 'E', - developers: ['HAL Labs'], - genres: ['Action', 'Fighting', '3D'], - }, - { - meta_score: 79, - title: 'Mario Party', - platform: 'N64', - date: 918424800000, - user_score: 8, - link: '/game/nintendo-64/mario-party', - esrb_rating: 'E', - developers: ['Hudson'], - genres: ['Miscellaneous', 'Party'], - }, - { - meta_score: 99, - title: 'The Legend of Zelda: Ocarina of Time', - platform: 'N64', - date: 911772000000, - user_score: 9.1, - link: '/game/nintendo-64/the-legend-of-zelda-ocarina-of-time', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action Adventure', 'Fantasy'], - }, - { - meta_score: 85, - title: 'F-Zero X', - platform: 'N64', - date: 907102800000, - user_score: 8.7, - link: '/game/nintendo-64/f-zero-x', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Futuristic'], - }, - { - meta_score: 92, - title: 'Banjo-Kazooie', - platform: 'N64', - date: 896562000000, - user_score: 9.2, - link: '/game/nintendo-64/banjo-kazooie', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: 65, - title: "Yoshi's Story", - platform: 'N64', - date: 888703200000, - user_score: 7.4, - link: '/game/nintendo-64/yoshis-story', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '2D'], - }, - { - meta_score: 88, - title: 'Diddy Kong Racing', - platform: 'N64', - date: 880322400000, - user_score: 8.4, - link: '/game/nintendo-64/diddy-kong-racing', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 96, - title: 'GoldenEye 007', - platform: 'N64', - date: 872456400000, - user_score: 8.9, - link: '/game/nintendo-64/goldeneye-007', - esrb_rating: 'T', - developers: ['Rare Ltd.'], - genres: ['Action', 'Shooter', 'First-Person', 'Modern'], - }, - { - meta_score: 88, - title: 'Star Fox 64', - platform: 'N64', - date: 867704400000, - user_score: 8.8, - link: '/game/nintendo-64/star-fox-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Rail'], - }, - { - meta_score: 90, - title: 'Blast Corps', - platform: 'N64', - date: 857080800000, - user_score: 8.4, - link: '/game/nintendo-64/blast-corps', - esrb_rating: 'E', - developers: ['Rare Ltd.'], - genres: ['Action', 'General'], - }, - { - meta_score: 83, - title: 'Mario Kart 64', - platform: 'N64', - date: 855525600000, - user_score: 8.6, - link: '/game/nintendo-64/mario-kart-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Kart'], - }, - { - meta_score: 92, - title: 'Wave Race 64', - platform: 'N64', - date: 846799200000, - user_score: 8.3, - link: '/game/nintendo-64/wave-race-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Driving', 'Racing', 'Snow / Water'], - }, - { - meta_score: 80, - title: 'Pilotwings 64', - platform: 'N64', - date: 843944400000, - user_score: 7.9, - link: '/game/nintendo-64/pilotwings-64', - esrb_rating: 'E', - developers: ['Paradigm Entertainment'], - genres: ['Simulation', 'General'], - }, - { - meta_score: 94, - title: 'Super Mario 64', - platform: 'N64', - date: 843685200000, - user_score: 9.1, - link: '/game/nintendo-64/super-mario-64', - esrb_rating: 'E', - developers: ['Nintendo'], - genres: ['Action', 'Platformer', '3D'], - }, - { - meta_score: null, - title: 'Project H.A.M.M.E.R.', - platform: 'WII', - date: null, - user_score: null, - link: '/game/wii/project-hammer', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', "Beat-'Em-Up", "Beat-'Em-Up", '2D'], - }, - { - meta_score: null, - title: 'Jet Impulse', - platform: 'DS', - date: null, - user_score: null, - link: '/game/ds/jet-impulse', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Simulation', 'Flight', 'Modern Jet', 'Combat'], - }, - { - meta_score: null, - title: 'Line Attack Heroes', - platform: 'WII', - date: null, - user_score: null, - link: '/game/wii/line-attack-heroes', - esrb_rating: '', - developers: ['GREZZO'], - genres: ['Action', 'General', 'General'], - }, - { - meta_score: null, - title: 'Wii U Play', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/wii-u-play', - esrb_rating: 'RP', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'Party', 'Party / Minigame'], - }, - { - meta_score: null, - title: 'Measure Up', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/measure-up', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General'], - }, - { - meta_score: null, - title: 'Make 10', - platform: 'DS', - date: null, - user_score: null, - link: '/game/ds/make-10', - esrb_rating: '', - developers: ['MuuMuu'], - genres: ['Miscellaneous', 'Puzzle', 'Puzzle', 'Logic', 'Logic'], - }, - { - meta_score: null, - title: 'ASH: Archaic Sealed Heat', - platform: 'DS', - date: null, - user_score: null, - link: '/game/ds/ash-archaic-sealed-heat', - esrb_rating: 'E10+', - developers: ['Mistwalker'], - genres: [ - 'Role-Playing', - 'Strategy', - 'Turn-Based', - 'General', - 'General', - 'Fantasy', - 'Tactics', - ], - }, - { - meta_score: null, - title: 'Nintendo Letterbox', - platform: 'DS', - date: null, - user_score: null, - link: '/game/ds/nintendo-letterbox', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Miscellaneous', 'General', 'General', 'Application'], - }, - { - meta_score: null, - title: 'Art Academy: Lessons for Everyone', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/art-academy-lessons-for-everyone', - esrb_rating: '', - developers: ['Nintendo', 'Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment', 'Edutainment'], - }, - { - meta_score: 68, - title: 'Wii Karaoke U', - platform: 'WIIU', - date: null, - user_score: 7.8, - link: '/game/wii-u/wii-karaoke-u', - esrb_rating: '', - developers: ['TOSE'], - genres: ['Action', 'Miscellaneous', 'Rhythm', 'Music', 'Music'], - }, - { - meta_score: null, - title: 'Art Academy', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/art-academy', - esrb_rating: '', - developers: ['Headstrong Games'], - genres: ['Miscellaneous', 'Edutainment'], - }, - { - meta_score: null, - title: 'Project Giant Robot', - platform: 'WIIU', - date: null, - user_score: null, - link: '/game/wii-u/project-giant-robot', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Simulation', 'Fighting', 'Vehicle', '3D', 'Combat'], - }, - { - meta_score: null, - title: 'Zero: Tsukihami no Kamen', - platform: 'WII', - date: null, - user_score: null, - link: '/game/wii/zero-tsukihami-no-kamen', - esrb_rating: '', - developers: ['Grasshopper Manufacture'], - genres: ['Action Adventure', 'Horror', 'Survival'], - }, - { - meta_score: null, - title: 'Blast Ball', - platform: '3DS', - date: null, - user_score: null, - link: '/game/3ds/blast-ball', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Sports', 'General'], - }, - { - meta_score: null, - title: 'FAST Racing Neo', - platform: '3DS', - date: null, - user_score: null, - link: '/game/3ds/fast-racing-neo', - esrb_rating: '', - developers: '["Shin\'en"]', - genres: ['Racing', 'Arcade', 'Futuristic'], - }, - { - meta_score: null, - title: 'Seasons of Heaven', - platform: 'Switch', - date: null, - user_score: null, - link: '/game/switch/seasons-of-heaven', - esrb_rating: '', - developers: ['AnyArts Productions'], - genres: ['Action Adventure', 'Survival', 'Open-World'], - }, - { - meta_score: null, - title: 'Metroid Prime 4', - platform: 'Switch', - date: null, - user_score: null, - link: '/game/switch/metroid-prime-4', - esrb_rating: '', - developers: ['Nintendo', 'Retro Studios'], - genres: ['Action', 'Shooter', 'First-Person', 'Arcade'], - }, - { - meta_score: null, - title: 'Yo-kai Watch 4', - platform: 'Switch', - date: null, - user_score: null, - link: '/game/switch/yo-kai-watch-4', - esrb_rating: 'E10+', - developers: ['Level 5'], - genres: ['Role-Playing', 'Trainer'], - }, - { - meta_score: null, - title: 'Splatoon 3: Expansion Pass Wave 2 - Side Order', - platform: 'Switch', - date: null, - user_score: null, - link: '/game/switch/splatoon-3-expansion-pass-wave-2---side-order', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Action', 'Shooter', 'Third-Person', 'Arcade'], - }, - { - meta_score: null, - title: 'Mario Kart 8 Deluxe: Booster Course Pass - Wave 6', - platform: 'Switch', - date: null, - user_score: null, - link: '/game/switch/mario-kart-8-deluxe-booster-course-pass---wave-6', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Racing', 'Arcade', 'Automobile'], - }, - { - meta_score: null, - title: 'Princess Peach for Nintendo Switch', - platform: 'Switch', - date: 1704060000000, - user_score: null, - link: '/game/switch/princess-peach-for-nintendo-switch', - esrb_rating: '', - developers: ['Nintendo'], - genres: ['Adventure', 'General'], - }, - { - meta_score: null, - title: "Luigi's Mansion: Dark Moon", - platform: 'Switch', - date: 1704060000000, - user_score: null, - link: '/game/switch/luigis-mansion-dark-moon', - esrb_rating: '', - developers: ['Next Level Games'], - genres: ['Action Adventure', 'General'], - }, -]; diff --git a/src/plugins/d3/examples/pie/Basic.tsx b/src/plugins/d3/examples/pie/Basic.tsx deleted file mode 100644 index 1b231820..00000000 --- a/src/plugins/d3/examples/pie/Basic.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const gamesByPlatform = groups(nintendoGames, (item) => item.platform); - return gamesByPlatform.map(([platform, games]) => ({ - name: platform, - value: games.length, - })); -} - -export const BasicPie = () => { - const data = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'pie', - data: data, - }, - ], - }, - legend: {enabled: true}, - title: { - text: 'Platforms', - style: {fontSize: '12px', fontWeight: 'normal'}, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/pie/Donut.tsx b/src/plugins/d3/examples/pie/Donut.tsx deleted file mode 100644 index b04aae42..00000000 --- a/src/plugins/d3/examples/pie/Donut.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const gamesByPlatform = groups(nintendoGames, (d) => d.esrb_rating || 'unknown'); - return gamesByPlatform.map(([value, games]) => ({ - name: value, - value: games.length, - })); -} - -export const Donut = () => { - const data = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'pie', - innerRadius: '50%', - data: data, - }, - ], - }, - legend: {enabled: true}, - title: { - text: 'ESRB ratings', - style: {fontSize: '12px', fontWeight: 'normal'}, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/pie/DonutWithTotals.tsx b/src/plugins/d3/examples/pie/DonutWithTotals.tsx deleted file mode 100644 index d65d949b..00000000 --- a/src/plugins/d3/examples/pie/DonutWithTotals.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; - -import {groups} from 'd3'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {CustomShapeRenderer} from '../../utils'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const gamesByPlatform = groups(nintendoGames, (d) => d.esrb_rating || 'unknown'); - return gamesByPlatform.map(([value, games]) => ({ - name: value, - value: games.length, - })); -} - -export const DonutWithTotals = () => { - const data = prepareData(); - const totals = data.reduce((sum, d) => sum + d.value, 0); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'pie', - innerRadius: '50%', - data: data, - renderCustomShape: CustomShapeRenderer.pieCenterText(`${totals}`), - }, - ], - }, - legend: {enabled: true}, - title: { - text: 'ESRB ratings', - style: {fontSize: '12px', fontWeight: 'normal'}, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/scatter/Basic.tsx b/src/plugins/d3/examples/scatter/Basic.tsx deleted file mode 100644 index e915d2a1..00000000 --- a/src/plugins/d3/examples/scatter/Basic.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData, ScatterSeries} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import nintendoGames from '../nintendoGames'; - -function prepareData() { - const dataset = nintendoGames.filter((d) => d.date && d.user_score); - const data = dataset.map((d) => ({ - x: d.date || undefined, - y: d.user_score || undefined, - custom: d, - })); - - return { - series: [ - { - data, - name: 'Nintendo games', - }, - ], - }; -} - -export const Basic = () => { - const {series} = prepareData(); - - const widgetData: ChartKitWidgetData = { - series: { - data: series.map((s) => ({ - type: 'scatter', - data: s.data.filter((d) => d.x), - name: s.name, - })), - }, - yAxis: [ - { - title: { - text: 'User score', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Release dates', - }, - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/examples/scatter/TwoYAxis.tsx b/src/plugins/d3/examples/scatter/TwoYAxis.tsx deleted file mode 100644 index 248aac5c..00000000 --- a/src/plugins/d3/examples/scatter/TwoYAxis.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; - -import {ChartKit} from '../../../../components/ChartKit'; -import type {ChartKitWidgetData} from '../../../../types'; -import {ExampleWrapper} from '../ExampleWrapper'; -import marsWeatherData from '../mars-weather'; - -export const TwoYAxis = () => { - const data = marsWeatherData as any[]; - const minTempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.min_temp, - })); - - const maxTempData = data.map((d) => ({ - x: dateTime({input: d.terrestrial_date, format: 'YYYY-MM-DD'}).valueOf(), - y: d.max_temp, - })); - - const widgetData: ChartKitWidgetData = { - series: { - data: [ - { - type: 'scatter', - data: minTempData, - name: 'Min Temperature', - yAxis: 0, - }, - { - type: 'scatter', - data: maxTempData, - name: 'Max Temperature', - yAxis: 1, - }, - ], - }, - yAxis: [ - { - title: { - text: 'Min', - }, - }, - { - title: { - text: 'Max', - }, - }, - ], - xAxis: { - type: 'datetime', - title: { - text: 'Terrestrial date', - }, - ticks: {pixelInterval: 200}, - }, - title: { - text: 'Mars weather', - }, - }; - - return ( - - - - ); -}; diff --git a/src/plugins/d3/index.ts b/src/plugins/d3/index.ts index 7b4311d2..1f8727d2 100644 --- a/src/plugins/d3/index.ts +++ b/src/plugins/d3/index.ts @@ -2,14 +2,15 @@ import React from 'react'; import {ChartKitPlugin} from '../../types'; +export {CustomShapeRenderer} from '@gravity-ui/charts'; export * from './types'; -export * from './utils'; /** * It is an experemental plugin * * DO NOT USE IT IN YOUR PRODUCTION * */ export const D3Plugin: ChartKitPlugin = { + // TODO: rename to 'gravity-chart' in the next major type: 'd3', renderer: React.lazy(() => import('./renderer/D3Widget')), }; diff --git a/src/plugins/d3/renderer/D3Widget.tsx b/src/plugins/d3/renderer/D3Widget.tsx index 0133ebe1..49de8ff7 100644 --- a/src/plugins/d3/renderer/D3Widget.tsx +++ b/src/plugins/d3/renderer/D3Widget.tsx @@ -1,87 +1,28 @@ import React from 'react'; +import {Chart} from '@gravity-ui/charts'; +import type {ChartProps, ChartRef} from '@gravity-ui/charts'; import afterFrame from 'afterframe'; -import {select} from 'd3'; -import type {DebouncedFunc} from 'lodash'; -import debounce from 'lodash/debounce'; +import {settings} from '../../../libs'; import type {ChartKitProps, ChartKitWidgetRef} from '../../../types'; -import {getRandomCKId, measurePerformance} from '../../../utils'; - -import {Chart} from './components'; -import {validateData} from './validation'; - -type ChartDimensions = { - width: number; - height: number; -}; +import {measurePerformance} from '../../../utils'; const D3Widget = React.forwardRef>( function D3Widget(props, forwardedRef) { const {data, onLoad, onRender, onChartLoad} = props; - const validatedData = React.useRef(); - const ref = React.useRef(null); - const debounced = React.useRef void> | undefined>(); - const [dimensions, setDimensions] = React.useState>(); + const lang = settings.get('lang'); const performanceMeasure = React.useRef | null>( measurePerformance(), ); + const chartRef = React.useRef(null); - const handleResize = React.useCallback(() => { - const parentElement = ref.current?.parentElement; - - if (parentElement) { - const {width, height} = parentElement.getBoundingClientRect(); - setDimensions({width, height}); - } - }, []); - - const debuncedHandleResize = React.useMemo(() => { - debounced.current?.cancel(); - debounced.current = debounce(handleResize, 200); - return debounced.current; - }, [handleResize]); - - React.useImperativeHandle( - forwardedRef, - () => ({ - reflow() { - debuncedHandleResize(); - }, - }), - [debuncedHandleResize], - ); - - React.useEffect(() => { - const selection = select(window); - // https://github.com/d3/d3-selection/blob/main/README.md#handling-events - const eventName = `resize.${getRandomCKId()}`; - selection.on(eventName, debuncedHandleResize); - - return () => { - // https://d3js.org/d3-selection/events#selection_on - selection.on(eventName, null); - }; - }, [debuncedHandleResize]); - - React.useEffect(() => { - // dimensions initialize - debuncedHandleResize(); - }, [debuncedHandleResize]); - - if (validatedData.current !== data) { - validateData(data); - validatedData.current = data; - } - - React.useLayoutEffect(() => { - if (onChartLoad) { - onChartLoad({}); - } - }, [onChartLoad]); + const handleResize: NonNullable = React.useCallback( + ({dimensions}) => { + if (!dimensions) { + return; + } - React.useLayoutEffect(() => { - if (dimensions?.width) { if (!performanceMeasure.current) { performanceMeasure.current = measurePerformance(); } @@ -96,23 +37,27 @@ const D3Widget = React.forwardRef - {dimensions?.width && dimensions?.height && ( - - )} - + React.useImperativeHandle( + forwardedRef, + () => ({ + reflow() { + chartRef.current?.reflow(); + }, + }), + [], ); + + React.useLayoutEffect(() => { + if (onChartLoad) { + onChartLoad({}); + } + }, [onChartLoad]); + + return ; }, ); diff --git a/src/plugins/d3/renderer/components/AxisX.tsx b/src/plugins/d3/renderer/components/AxisX.tsx deleted file mode 100644 index 3b5229a8..00000000 --- a/src/plugins/d3/renderer/components/AxisX.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import React from 'react'; - -import {select} from 'd3'; -import type {AxisDomain, AxisScale} from 'd3'; - -import {block} from '../../../../utils/cn'; -import type {ChartScale, PreparedAxis, PreparedSplit} from '../hooks'; -import { - formatAxisTickLabel, - getAxisTitleRows, - getClosestPointsRange, - getMaxTickCount, - getScaleTicks, - getTicksCount, - handleOverflowingText, -} from '../utils'; -import {axisBottom} from '../utils/axis-generators'; - -const b = block('d3-axis'); - -type Props = { - axis: PreparedAxis; - width: number; - height: number; - scale: ChartScale; - split: PreparedSplit; -}; - -function getLabelFormatter({axis, scale}: {axis: PreparedAxis; scale: ChartScale}) { - const ticks = getScaleTicks(scale as AxisScale); - const tickStep = getClosestPointsRange(axis, ticks); - - return (value: any) => { - if (!axis.labels.enabled) { - return ''; - } - - return formatAxisTickLabel({ - axis, - value, - step: tickStep, - }); - }; -} - -export function getTitlePosition(args: {axis: PreparedAxis; width: number; rowCount: number}) { - const {axis, width, rowCount} = args; - if (rowCount < 1) { - return {x: 0, y: 0}; - } - - let x; - const y = - axis.title.height / rowCount + axis.title.margin + axis.labels.height + axis.labels.margin; - - switch (axis.title.align) { - case 'left': { - x = axis.title.width / 2; - break; - } - case 'right': { - x = width - axis.title.width / 2; - break; - } - case 'center': { - x = width / 2; - break; - } - } - - return {x, y}; -} - -export const AxisX = React.memo(function AxisX(props: Props) { - const {axis, width, height: totalHeight, scale, split} = props; - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return; - } - - let tickItems: [number, number][] = []; - if (axis.grid.enabled) { - tickItems = new Array(split.plots.length || 1).fill(null).map((_, index) => { - const top = split.plots[index]?.top || 0; - const height = split.plots[index]?.height || totalHeight; - - return [-top, -(top + height)]; - }); - } - - const xAxisGenerator = axisBottom({ - scale: scale as AxisScale, - ticks: { - items: tickItems, - labelFormat: getLabelFormatter({axis, scale}), - labelsPaddings: axis.labels.padding, - labelsMargin: axis.labels.margin, - labelsStyle: axis.labels.style, - labelsMaxWidth: axis.labels.maxWidth, - labelsLineHeight: axis.labels.lineHeight, - count: getTicksCount({axis, range: width}), - maxTickCount: getMaxTickCount({axis, width}), - rotation: axis.labels.rotation, - }, - domain: { - size: width, - color: axis.lineColor, - }, - }); - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - - svgElement.call(xAxisGenerator).attr('class', b()); - - // add an axis header if necessary - if (axis.title.text) { - const titleRows = getAxisTitleRows({axis, textMaxWidth: width}); - svgElement - .append('text') - .attr('class', b('title')) - .attr('transform', () => { - const {x, y} = getTitlePosition({axis, width, rowCount: titleRows.length}); - return `translate(${x}, ${y})`; - }) - .attr('font-size', axis.title.style.fontSize) - .attr('text-anchor', 'middle') - .selectAll('tspan') - .data(titleRows) - .join('tspan') - .attr('x', 0) - .attr('y', (d) => d.y) - .text((d) => d.text) - .each((_d, index, nodes) => { - if (index === axis.title.maxRowCount - 1) { - handleOverflowingText(nodes[index] as SVGTSpanElement, width); - } - }); - } - }, [axis, width, totalHeight, scale, split]); - - return ; -}); diff --git a/src/plugins/d3/renderer/components/AxisY.tsx b/src/plugins/d3/renderer/components/AxisY.tsx deleted file mode 100644 index b9c8fdf6..00000000 --- a/src/plugins/d3/renderer/components/AxisY.tsx +++ /dev/null @@ -1,269 +0,0 @@ -import React from 'react'; - -import {axisLeft, axisRight, line, select} from 'd3'; -import type {Axis, AxisDomain, AxisScale, Selection} from 'd3'; - -import {block} from '../../../../utils/cn'; -import type {ChartScale, PreparedAxis, PreparedSplit} from '../hooks'; -import { - calculateCos, - calculateSin, - formatAxisTickLabel, - getAxisHeight, - getAxisTitleRows, - getClosestPointsRange, - getScaleTicks, - getTicksCount, - handleOverflowingText, - parseTransformStyle, - setEllipsisForOverflowTexts, - wrapText, -} from '../utils'; - -const b = block('d3-axis'); - -type Props = { - axes: PreparedAxis[]; - scale: ChartScale[]; - width: number; - height: number; - split: PreparedSplit; -}; - -function transformLabel(args: {node: Element; axis: PreparedAxis}) { - const {node, axis} = args; - let topOffset = axis.labels.lineHeight / 2; - let leftOffset = axis.labels.margin; - - if (axis.position === 'left') { - leftOffset = leftOffset * -1; - } - - if (axis.labels.rotation) { - if (axis.labels.rotation > 0) { - leftOffset -= axis.labels.lineHeight * calculateSin(axis.labels.rotation); - topOffset = axis.labels.lineHeight * calculateCos(axis.labels.rotation); - - if (axis.labels.rotation % 360 === 90) { - topOffset = (node?.getBoundingClientRect().width || 0) / 2; - } - } else { - topOffset = 0; - - if (axis.labels.rotation % 360 === -90) { - topOffset = -(node?.getBoundingClientRect().width || 0) / 2; - } - } - - return `translate(${leftOffset}px, ${topOffset}px) rotate(${axis.labels.rotation}deg)`; - } - - return `translate(${leftOffset}px, ${topOffset}px)`; -} - -function getAxisGenerator(args: { - preparedAxis: PreparedAxis; - axisGenerator: Axis; - width: number; - height: number; - scale: ChartScale; -}) { - const {preparedAxis, axisGenerator: generator, width, height, scale} = args; - const tickSize = preparedAxis.grid.enabled ? width * -1 : 0; - const step = getClosestPointsRange(preparedAxis, getScaleTicks(scale as AxisScale)); - - let axisGenerator = generator - .tickSize(tickSize) - .tickPadding(preparedAxis.labels.margin) - .tickFormat((value) => { - if (!preparedAxis.labels.enabled) { - return ''; - } - - return formatAxisTickLabel({ - axis: preparedAxis, - value, - step, - }); - }); - - const ticksCount = getTicksCount({axis: preparedAxis, range: height}); - if (ticksCount) { - axisGenerator = axisGenerator.ticks(ticksCount); - } - - return axisGenerator; -} - -function getTitlePosition(args: {axis: PreparedAxis; axisHeight: number; rowCount: number}) { - const {axis, axisHeight, rowCount} = args; - if (rowCount < 1) { - return {x: 0, y: 0}; - } - - const x = -( - axis.title.height - - axis.title.height / rowCount + - axis.title.margin + - axis.labels.margin + - axis.labels.width - ); - let y; - - switch (axis.title.align) { - case 'left': { - y = axisHeight - axis.title.width / 2; - break; - } - case 'right': { - y = axis.title.width / 2; - break; - } - case 'center': { - y = axisHeight / 2; - break; - } - } - - return {x, y}; -} - -export const AxisY = (props: Props) => { - const {axes, width, height: totalHeight, scale, split} = props; - const height = getAxisHeight({split, boundsHeight: totalHeight}); - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return; - } - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - - const axisSelection = svgElement - .selectAll('axis') - .data(axes) - .join('g') - .attr('class', b()) - .style('transform', (d) => { - const top = split.plots[d.plotIndex]?.top || 0; - if (d.position === 'left') { - return `translate(0, ${top}px)`; - } - - return `translate(${width}px, 0)`; - }); - - axisSelection.each((d, index, node) => { - const seriesScale = scale[index]; - const axisItem = select(node[index]) as Selection< - SVGGElement, - PreparedAxis, - any, - unknown - >; - const yAxisGenerator = getAxisGenerator({ - axisGenerator: - d.position === 'left' - ? axisLeft(seriesScale as AxisScale) - : axisRight(seriesScale as AxisScale), - preparedAxis: d, - height, - width, - scale: seriesScale, - }); - yAxisGenerator(axisItem); - - if (d.labels.enabled) { - const tickTexts = axisItem - .selectAll('.tick text') - // The offset must be applied before the labels are rotated. - // Therefore, we reset the values and make an offset in transform attribute. - // FIXME: give up axisLeft(d3) and switch to our own generation method - .attr('x', null) - .attr('dy', null) - .style('font-size', d.labels.style.fontSize) - .style('transform', function () { - return transformLabel({node: this, axis: d}); - }); - const textMaxWidth = - !d.labels.rotation || Math.abs(d.labels.rotation) % 360 !== 90 - ? d.labels.maxWidth - : (height - d.labels.padding * (tickTexts.size() - 1)) / tickTexts.size(); - tickTexts.call(setEllipsisForOverflowTexts, textMaxWidth); - } - - // remove overlapping ticks - // Note: this method do not prepared for rotated labels - if (!d.labels.rotation) { - let elementY = 0; - axisItem - .selectAll('.tick') - .filter(function (_d, tickIndex) { - const tickNode = this as unknown as Element; - const r = tickNode.getBoundingClientRect(); - - if (r.bottom > elementY && tickIndex !== 0) { - return true; - } - elementY = r.top - d.labels.padding; - return false; - }) - .remove(); - } - - return axisItem; - }); - - axisSelection - .select('.domain') - .attr('d', () => { - const points: [number, number][] = [ - [0, 0], - [0, height], - ]; - - return line()(points); - }) - .style('stroke', (d) => d.lineColor || ''); - - svgElement.selectAll('.tick').each((_d, index, nodes) => { - const tickNode = select(nodes[index]); - if (parseTransformStyle(tickNode.attr('transform')).y === height) { - // Remove stroke from tick that has the same y coordinate like domain - tickNode.select('line').style('stroke', 'none'); - } - }); - - axisSelection - .append('text') - .attr('class', b('title')) - .attr('text-anchor', 'middle') - .attr('font-size', (d) => d.title.style.fontSize) - .attr('transform', (d) => { - const titleRows = wrapText({ - text: d.title.text, - style: d.title.style, - width: height, - }); - const rowCount = Math.min(titleRows.length, d.title.maxRowCount); - const {x, y} = getTitlePosition({axis: d, axisHeight: height, rowCount}); - const angle = d.position === 'left' ? -90 : 90; - return `translate(${x}, ${y}) rotate(${angle})`; - }) - .selectAll('tspan') - .data((d) => getAxisTitleRows({axis: d, textMaxWidth: height})) - .join('tspan') - .attr('x', 0) - .attr('y', (d) => d.y) - .text((d) => d.text) - .each((_d, index, nodes) => { - if (index === nodes.length - 1) { - handleOverflowingText(nodes[index] as SVGTSpanElement, height); - } - }); - }, [axes, width, height, scale, split]); - - return ; -}; diff --git a/src/plugins/d3/renderer/components/Chart.tsx b/src/plugins/d3/renderer/components/Chart.tsx deleted file mode 100644 index e4c2401d..00000000 --- a/src/plugins/d3/renderer/components/Chart.tsx +++ /dev/null @@ -1,249 +0,0 @@ -import React from 'react'; - -import {pointer} from 'd3'; -import throttle from 'lodash/throttle'; - -import type {ChartKitWidgetData} from '../../../../types'; -import {block} from '../../../../utils/cn'; -import {getD3Dispatcher} from '../d3-dispatcher'; -import {useAxisScales, useChartDimensions, useChartOptions, useSeries, useShapes} from '../hooks'; -import {getYAxisWidth} from '../hooks/useChartDimensions/utils'; -import {getPreparedXAxis} from '../hooks/useChartOptions/x-axis'; -import {getPreparedYAxis} from '../hooks/useChartOptions/y-axis'; -import {useSplit} from '../hooks/useSplit'; -import {getClosestPoints} from '../utils/get-closest-data'; - -import {AxisX} from './AxisX'; -import {AxisY} from './AxisY'; -import {Legend} from './Legend'; -import {PlotTitle} from './PlotTitle'; -import {Title} from './Title'; -import {Tooltip} from './Tooltip'; - -import './styles.scss'; - -const b = block('d3'); - -const THROTTLE_DELAY = 50; - -type Props = { - width: number; - height: number; - data: ChartKitWidgetData; -}; - -export const Chart = (props: Props) => { - const {width, height, data} = props; - const svgRef = React.useRef(null); - const htmlLayerRef = React.useRef(null); - const dispatcher = React.useMemo(() => { - return getD3Dispatcher(); - }, []); - const {chart, title, tooltip} = useChartOptions({ - data, - }); - const xAxis = React.useMemo( - () => getPreparedXAxis({xAxis: data.xAxis, width, series: data.series.data}), - [data, width], - ); - const yAxis = React.useMemo( - () => - getPreparedYAxis({ - series: data.series.data, - yAxis: data.yAxis, - height, - }), - [data, height], - ); - - const { - legendItems, - legendConfig, - preparedSeries, - preparedSeriesOptions, - preparedLegend, - handleLegendItemClick, - } = useSeries({ - chartWidth: width, - chartHeight: height, - chartMargin: chart.margin, - series: data.series, - legend: data.legend, - preparedYAxis: yAxis, - }); - const {boundsWidth, boundsHeight} = useChartDimensions({ - width, - height, - margin: chart.margin, - preparedLegend, - preparedXAxis: xAxis, - preparedYAxis: yAxis, - preparedSeries: preparedSeries, - }); - const preparedSplit = useSplit({split: data.split, boundsHeight, chartWidth: width}); - const {xScale, yScale} = useAxisScales({ - boundsWidth, - boundsHeight, - series: preparedSeries, - xAxis, - yAxis, - split: preparedSplit, - }); - const {shapes, shapesData} = useShapes({ - boundsWidth, - boundsHeight, - dispatcher, - series: preparedSeries, - seriesOptions: preparedSeriesOptions, - xAxis, - xScale, - yAxis, - yScale, - split: preparedSplit, - htmlLayout: htmlLayerRef.current, - }); - - const clickHandler = data.chart?.events?.click; - React.useEffect(() => { - if (clickHandler) { - dispatcher.on('click-chart', clickHandler); - } - - return () => { - dispatcher.on('click-chart', null); - }; - }, [dispatcher, clickHandler]); - - const boundsOffsetTop = chart.margin.top; - // We only need to consider the width of the first left axis - const boundsOffsetLeft = chart.margin.left + getYAxisWidth(yAxis[0]); - - const isOutsideBounds = React.useCallback( - (x: number, y: number) => { - return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight; - }, - [boundsHeight, boundsWidth], - ); - - const handleMouseMove: React.MouseEventHandler = (event) => { - const [pointerX, pointerY] = pointer(event, svgRef.current); - const x = pointerX - boundsOffsetLeft; - const y = pointerY - boundsOffsetTop; - if (isOutsideBounds(x, y)) { - dispatcher.call('hover-shape', {}, undefined); - return; - } - - const closest = getClosestPoints({ - position: [x, y], - shapesData, - }); - dispatcher.call('hover-shape', event.target, closest, [pointerX, pointerY]); - }; - const throttledHandleMouseMove = throttle(handleMouseMove, THROTTLE_DELAY); - - const handleMouseLeave = () => { - throttledHandleMouseMove.cancel(); - dispatcher.call('hover-shape', {}, undefined); - }; - - const handleChartClick = React.useCallback( - (event: React.MouseEvent) => { - const [pointerX, pointerY] = pointer(event, svgRef.current); - const x = pointerX - boundsOffsetLeft; - const y = pointerY - boundsOffsetTop; - if (isOutsideBounds(x, y)) { - return; - } - - const items = getClosestPoints({ - position: [x, y], - shapesData, - }); - const selected = items?.find((item) => item.closest); - if (!selected) { - return; - } - - dispatcher.call( - 'click-chart', - undefined, - {point: selected.data, series: selected.series}, - event, - ); - }, - [boundsOffsetLeft, boundsOffsetTop, dispatcher, isOutsideBounds, shapesData], - ); - - return ( - - - {title && } - - {preparedSplit.plots.map((plot, index) => { - return ; - })} - - - {xScale && yScale?.length && ( - - - - - - - )} - {shapes} - - {preparedLegend.enabled && ( - - )} - -
- - - ); -}; diff --git a/src/plugins/d3/renderer/components/Legend.tsx b/src/plugins/d3/renderer/components/Legend.tsx deleted file mode 100644 index e8e48bc6..00000000 --- a/src/plugins/d3/renderer/components/Legend.tsx +++ /dev/null @@ -1,356 +0,0 @@ -import React from 'react'; - -import {line as lineGenerator, scaleLinear, select, symbol} from 'd3'; -import type {AxisDomain, AxisScale, BaseType, Selection} from 'd3'; - -import {block} from '../../../../utils/cn'; -import {CONTINUOUS_LEGEND_SIZE} from '../constants'; -import type { - LegendConfig, - LegendItem, - OnLegendItemClick, - PreparedLegend, - PreparedSeries, - SymbolLegendSymbol, -} from '../hooks'; -import {getLineDashArray} from '../hooks/useShapes/utils'; -import {createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol} from '../utils'; -import {axisBottom} from '../utils/axis-generators'; - -const b = block('d3-legend'); - -type Props = { - boundsWidth: number; - chartSeries: PreparedSeries[]; - legend: PreparedLegend; - items: LegendItem[][]; - config: LegendConfig; - onItemClick: OnLegendItemClick; -}; - -const getLegendPosition = (args: { - align: PreparedLegend['align']; - contentWidth: number; - width: number; - offsetWidth: number; -}) => { - const {align, offsetWidth, width, contentWidth} = args; - const top = 0; - - if (align === 'left') { - return {top, left: offsetWidth}; - } - - if (align === 'right') { - return {top, left: offsetWidth + width - contentWidth}; - } - - return {top, left: offsetWidth + width / 2 - contentWidth / 2}; -}; - -const appendPaginator = (args: { - container: Selection; - offset: number; - maxPage: number; - legend: PreparedLegend; - transform: string; - onArrowClick: (offset: number) => void; -}) => { - const {container, offset, maxPage, legend, transform, onArrowClick} = args; - const paginationLine = container.append('g').attr('class', b('pagination')); - let computedWidth = 0; - - paginationLine - .append('text') - .text('▲') - .attr('class', function () { - return b('pagination-arrow', {inactive: offset === 0}); - }) - .style('font-size', legend.itemStyle.fontSize) - .each(function () { - computedWidth += this.getComputedTextLength(); - }) - .on('click', function () { - if (offset - 1 >= 0) { - onArrowClick(offset - 1); - } - }); - paginationLine - .append('text') - .text(`${offset + 1}/${maxPage}`) - .attr('class', b('pagination-counter')) - .attr('x', computedWidth) - .style('font-size', legend.itemStyle.fontSize) - .each(function () { - computedWidth += this.getComputedTextLength(); - }); - paginationLine - .append('text') - .text('▼') - .attr('class', function () { - return b('pagination-arrow', {inactive: offset === maxPage - 1}); - }) - .attr('x', computedWidth) - .style('font-size', legend.itemStyle.fontSize) - .on('click', function () { - if (offset + 1 < maxPage) { - onArrowClick(offset + 1); - } - }); - paginationLine.attr('transform', transform); -}; - -const legendSymbolGenerator = lineGenerator<{x: number; y: number}>() - .x((d) => d.x) - .y((d) => d.y); - -function renderLegendSymbol(args: { - selection: Selection; - legend: PreparedLegend; -}) { - const {selection, legend} = args; - const line = selection.data(); - - const getXPosition = (i: number) => { - return line.slice(0, i).reduce((acc, legendItem) => { - return ( - acc + - legendItem.symbol.width + - legendItem.symbol.padding + - legendItem.textWidth + - legend.itemDistance - ); - }, 0); - }; - - selection.each(function (d, i) { - const element = select(this); - const x = getXPosition(i); - const className = b('item-symbol', {shape: d.symbol.shape, unselected: !d.visible}); - const color = d.visible ? d.color : ''; - - switch (d.symbol.shape) { - case 'path': { - const y = legend.lineHeight / 2; - const points = [ - {x: x, y}, - {x: x + d.symbol.width, y}, - ]; - - element - .append('path') - .attr('d', legendSymbolGenerator(points)) - .attr('fill', 'none') - .attr('stroke-width', d.symbol.strokeWidth) - .attr('class', className) - .style('stroke', color); - - if (d.dashStyle) { - element.attr( - 'stroke-dasharray', - getLineDashArray(d.dashStyle, d.symbol.strokeWidth), - ); - } - - break; - } - case 'rect': { - const y = (legend.lineHeight - d.symbol.height) / 2; - element - .append('rect') - .attr('x', x) - .attr('y', y) - .attr('width', d.symbol.width) - .attr('height', d.symbol.height) - .attr('rx', d.symbol.radius) - .attr('class', className) - .style('fill', color); - - break; - } - case 'symbol': { - const y = legend.lineHeight / 2; - - element - .append('svg:path') - .attr('d', () => { - const scatterSymbol = getSymbol( - (d.symbol as SymbolLegendSymbol).symbolType, - ); - - // D3 takes size as square pixels, so we need to make square pixels size by multiplying - // https://d3js.org/d3-shape/symbol#symbol - return symbol(scatterSymbol, d.symbol.width * d.symbol.width)(); - }) - .attr('transform', () => { - return 'translate(' + x + ',' + y + ')'; - }) - .attr('class', className) - .style('fill', color); - - break; - } - } - }); -} - -export const Legend = (props: Props) => { - const {boundsWidth, chartSeries, legend, items, config, onItemClick} = props; - const ref = React.useRef(null); - const [paginationOffset, setPaginationOffset] = React.useState(0); - - React.useEffect(() => { - setPaginationOffset(0); - }, [boundsWidth]); - - React.useEffect(() => { - if (!ref.current) { - return; - } - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - - let legendWidth = 0; - if (legend.type === 'discrete') { - const limit = config.pagination?.limit; - const pageItems = - typeof limit === 'number' - ? items.slice(paginationOffset * limit, paginationOffset * limit + limit) - : items; - pageItems.forEach((line, lineIndex) => { - const legendLine = svgElement.append('g').attr('class', b('line')); - const legendItemTemplate = legendLine - .selectAll('legend-history') - .data(line) - .enter() - .append('g') - .attr('class', b('item')) - .on('click', function (e, d) { - onItemClick({name: d.name, metaKey: e.metaKey}); - }); - - const getXPosition = (i: number) => { - return line.slice(0, i).reduce((acc, legendItem) => { - return ( - acc + - legendItem.symbol.width + - legendItem.symbol.padding + - legendItem.textWidth + - legend.itemDistance - ); - }, 0); - }; - - renderLegendSymbol({selection: legendItemTemplate, legend}); - - legendItemTemplate - .append('text') - .attr('x', function (legendItem, i) { - return ( - getXPosition(i) + legendItem.symbol.width + legendItem.symbol.padding - ); - }) - .attr('height', legend.lineHeight) - .attr('class', function (d) { - const mods = {selected: d.visible, unselected: !d.visible}; - return b('item-text', mods); - }) - .text(function (d) { - return ('name' in d && d.name) as string; - }) - .style('font-size', legend.itemStyle.fontSize); - - const contentWidth = legendLine.node()?.getBoundingClientRect().width || 0; - const {left} = getLegendPosition({ - align: legend.align, - width: boundsWidth, - offsetWidth: 0, - contentWidth, - }); - const top = legend.lineHeight * lineIndex; - - legendLine.attr('transform', `translate(${[left, top].join(',')})`); - }); - legendWidth = boundsWidth; - - if (config.pagination) { - const transform = `translate(${[ - 0, - legend.lineHeight * config.pagination.limit + legend.lineHeight / 2, - ].join(',')})`; - appendPaginator({ - container: svgElement, - offset: paginationOffset, - maxPage: config.pagination.maxPage, - legend, - transform, - onArrowClick: setPaginationOffset, - }); - } - } else { - // gradient rect - const domain = legend.colorScale.domain ?? []; - const rectHeight = CONTINUOUS_LEGEND_SIZE.height; - svgElement.call(createGradientRect, { - y: legend.title.height + legend.title.margin, - height: rectHeight, - width: legend.width, - interpolator: getContinuesColorFn({ - values: [0, 1], - colors: legend.colorScale.colors, - stops: legend.colorScale.stops, - }), - }); - - // ticks - const xAxisGenerator = axisBottom({ - scale: scaleLinear(domain, [0, legend.width]) as AxisScale, - ticks: { - items: [[0, -rectHeight]], - labelsMargin: legend.ticks.labelsMargin, - labelsLineHeight: legend.ticks.labelsLineHeight, - maxTickCount: 4, - tickColor: '#fff', - }, - domain: { - size: legend.width, - color: 'transparent', - }, - }); - const tickTop = legend.title.height + legend.title.margin + rectHeight; - svgElement - .append('g') - .attr('transform', `translate(0, ${tickTop})`) - .call(xAxisGenerator); - legendWidth = legend.width; - } - - if (legend.title.enable) { - const {maxWidth: labelWidth} = getLabelsSize({ - labels: [legend.title.text], - style: legend.title.style, - }); - svgElement - .append('g') - .attr('class', b('title')) - .append('text') - .attr('dx', legend.width / 2 - labelWidth / 2) - .attr('font-weight', legend.title.style.fontWeight ?? null) - .attr('font-size', legend.title.style.fontSize ?? null) - .attr('fill', legend.title.style.fontColor ?? null) - .style('alignment-baseline', 'before-edge') - .text(legend.title.text); - } - - const {left} = getLegendPosition({ - align: legend.align, - width: boundsWidth, - offsetWidth: config.offset.left, - contentWidth: legendWidth, - }); - svgElement.attr('transform', `translate(${[left, config.offset.top].join(',')})`); - }, [boundsWidth, chartSeries, onItemClick, legend, items, config, paginationOffset]); - - return ; -}; diff --git a/src/plugins/d3/renderer/components/PlotTitle.tsx b/src/plugins/d3/renderer/components/PlotTitle.tsx deleted file mode 100644 index 00f5a2ae..00000000 --- a/src/plugins/d3/renderer/components/PlotTitle.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -import {block} from '../../../../utils/cn'; -import type {PreparedPlotTitle} from '../hooks/useSplit/types'; - -const b = block('d3-plot-title'); - -type Props = { - title?: PreparedPlotTitle; -}; - -export const PlotTitle = (props: Props) => { - const {title} = props; - - if (!title) { - return null; - } - - const {x, y, text, style, height} = title; - - return ( - - {text} - - ); -}; diff --git a/src/plugins/d3/renderer/components/Title.tsx b/src/plugins/d3/renderer/components/Title.tsx deleted file mode 100644 index ac31ce88..00000000 --- a/src/plugins/d3/renderer/components/Title.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; - -import {block} from '../../../../utils/cn'; -import type {PreparedTitle} from '../hooks'; - -const b = block('d3-title'); - -type Props = PreparedTitle & { - chartWidth: number; -}; - -export const Title = (props: Props) => { - const {chartWidth, text, height, style} = props; - - return ( - - {text} - - ); -}; diff --git a/src/plugins/d3/renderer/components/Tooltip/DefaultContent.tsx b/src/plugins/d3/renderer/components/Tooltip/DefaultContent.tsx deleted file mode 100644 index 1a40ab9d..00000000 --- a/src/plugins/d3/renderer/components/Tooltip/DefaultContent.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import React from 'react'; - -import {dateTime} from '@gravity-ui/date-utils'; -import get from 'lodash/get'; - -import type { - ChartKitWidgetSeriesData, - TooltipDataChunk, - TreemapSeriesData, - WaterfallSeriesData, -} from '../../../../../types'; -import {block} from '../../../../../utils/cn'; -import {formatNumber} from '../../../../shared'; -import type {PreparedAxis, PreparedPieSeries, PreparedWaterfallSeries} from '../../hooks'; -import {getDataCategoryValue, getWaterfallPointSubtotal} from '../../utils'; - -const b = block('d3-tooltip'); - -type Props = { - hovered: TooltipDataChunk[]; - xAxis: PreparedAxis; - yAxis: PreparedAxis; -}; - -const DEFAULT_DATE_FORMAT = 'DD.MM.YY'; - -const getRowData = (fieldName: 'x' | 'y', axis: PreparedAxis, data: ChartKitWidgetSeriesData) => { - switch (axis.type) { - case 'category': { - const categories = get(axis, 'categories', [] as string[]); - return getDataCategoryValue({axisDirection: fieldName, categories, data}); - } - case 'datetime': { - const value = get(data, fieldName); - if (!value) { - return undefined; - } - return dateTime({input: value}).format(DEFAULT_DATE_FORMAT); - } - case 'linear': - default: { - const value = get(data, fieldName) as unknown as number; - return formatNumber(value); - } - } -}; - -const getXRowData = (xAxis: PreparedAxis, data: ChartKitWidgetSeriesData) => - getRowData('x', xAxis, data); - -const getYRowData = (yAxis: PreparedAxis, data: ChartKitWidgetSeriesData) => - getRowData('y', yAxis, data); - -const getMeasureValue = (data: TooltipDataChunk[], xAxis: PreparedAxis, yAxis: PreparedAxis) => { - if (data.every((item) => ['pie', 'treemap', 'waterfall'].includes(item.series.type))) { - return null; - } - - if (data.some((item) => item.series.type === 'bar-y')) { - return getYRowData(yAxis, data[0]?.data); - } - - return getXRowData(xAxis, data[0]?.data); -}; - -export const DefaultContent = ({hovered, xAxis, yAxis}: Props) => { - const measureValue = getMeasureValue(hovered, xAxis, yAxis); - - return ( - <> - {measureValue &&
{measureValue}
} - {hovered.map(({data, series, closest}, i) => { - const id = `${get(series, 'id')}_${i}`; - const color = get(series, 'color'); - - switch (series.type) { - case 'scatter': - case 'line': - case 'area': - case 'bar-x': { - const value = ( - - {series.name}: {getYRowData(yAxis, data)} - - ); - return ( -
-
-
{closest ? {value} : {value}}
-
- ); - } - case 'waterfall': { - const isTotal = get(data, 'total', false); - const subTotal = getWaterfallPointSubtotal( - data as WaterfallSeriesData, - series as PreparedWaterfallSeries, - ); - - return ( -
- {!isTotal && ( - -
- {getXRowData(xAxis, data)} -
-
- {series.name}  - {getYRowData(yAxis, data)} -
-
- )} -
- {isTotal ? 'Total' : 'Subtotal'}: {subTotal} -
-
- ); - } - case 'bar-y': { - const value = ( - - {series.name}: {getXRowData(xAxis, data)} - - ); - return ( -
-
-
{closest ? {value} : {value}}
-
- ); - } - case 'pie': - case 'treemap': { - const seriesData = data as PreparedPieSeries | TreemapSeriesData; - - return ( -
-
- {seriesData.name || seriesData.id}  - {seriesData.value} -
- ); - } - default: { - return null; - } - } - })} - - ); -}; diff --git a/src/plugins/d3/renderer/components/Tooltip/index.tsx b/src/plugins/d3/renderer/components/Tooltip/index.tsx deleted file mode 100644 index 8bb77b3c..00000000 --- a/src/plugins/d3/renderer/components/Tooltip/index.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; - -import {Popup, useVirtualElementRef} from '@gravity-ui/uikit'; -import type {Dispatch} from 'd3'; -import isNil from 'lodash/isNil'; - -import {block} from '../../../../../utils/cn'; -import type {PreparedAxis, PreparedTooltip} from '../../hooks'; -import {useTooltip} from '../../hooks'; - -import {DefaultContent} from './DefaultContent'; - -const b = block('d3-tooltip'); - -type TooltipProps = { - dispatcher: Dispatch; - tooltip: PreparedTooltip; - svgContainer: SVGSVGElement | null; - xAxis: PreparedAxis; - yAxis: PreparedAxis; -}; - -export const Tooltip = (props: TooltipProps) => { - const {tooltip, xAxis, yAxis, svgContainer, dispatcher} = props; - const {hovered, pointerPosition} = useTooltip({dispatcher, tooltip}); - const containerRect = svgContainer?.getBoundingClientRect() || {left: 0, top: 0}; - const left = (pointerPosition?.[0] || 0) + containerRect.left; - const top = (pointerPosition?.[1] || 0) + containerRect.top; - const anchorRef = useVirtualElementRef({rect: {top, left}}); - const content = React.useMemo(() => { - if (!hovered) { - return null; - } - - const customTooltip = tooltip.renderer?.({hovered}); - return isNil(customTooltip) ? ( - - ) : ( - customTooltip - ); - }, [hovered, tooltip, xAxis, yAxis]); - - React.useEffect(() => { - window.dispatchEvent(new CustomEvent('scroll')); - }, [left, top]); - - return hovered?.length ? ( - -
{content}
-
- ) : null; -}; diff --git a/src/plugins/d3/renderer/components/index.ts b/src/plugins/d3/renderer/components/index.ts deleted file mode 100644 index 03285e7f..00000000 --- a/src/plugins/d3/renderer/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {Chart} from './Chart'; diff --git a/src/plugins/d3/renderer/components/styles.scss b/src/plugins/d3/renderer/components/styles.scss deleted file mode 100644 index 3b673fd0..00000000 --- a/src/plugins/d3/renderer/components/styles.scss +++ /dev/null @@ -1,148 +0,0 @@ -.chartkit-d3 { - position: absolute; - - &__html-layer { - display: contents; - - & > * { - transform: inherit; - } - } -} - -.chartkit-d3-axis { - & .domain { - stroke: var(--g-color-line-generic-active); - } - - & .tick text { - color: var(--g-color-text-secondary); - alignment-baseline: after-edge; - } - - & .tick line, - & .tick path { - stroke: var(--g-color-line-generic); - } - - &__title { - alignment-baseline: after-edge; - fill: var(--g-color-text-secondary); - } - - &__title tspan { - alignment-baseline: after-edge; - } -} - -.chartkit-d3-legend { - color: var(--g-color-text-secondary); - - &__title { - fill: var(--g-color-text-secondary); - } - - &__item { - cursor: pointer; - user-select: none; - } - - &__item-symbol { - &_shape_rect#{&}_unselected { - fill: var(--g-color-text-hint); - } - - &_shape_path#{&}_unselected { - stroke: var(--g-color-text-hint); - } - - &_shape_symbol#{&}_unselected { - fill: var(--g-color-text-hint); - } - } - - &__item-text { - fill: var(--g-color-text-secondary); - alignment-baseline: before-edge; - - &_unselected { - fill: var(--g-color-text-hint); - } - - &:hover { - fill: var(--g-color-text-complementary); - } - } - - &__pagination { - fill: var(--g-color-text-primary); - user-select: none; - } - - &__pagination-counter, - &__pagination-arrow { - alignment-baseline: middle; - } - - &__pagination-arrow { - fill: var(--g-color-text-brand); - cursor: pointer; - - &_inactive { - fill: var(--g-color-base-generic-accent-disabled); - cursor: inherit; - } - - &:hover:not(#{&}_inactive) { - fill: var(--g-color-base-brand-hover); - } - } -} - -.chartkit-d3-title { - font-size: var(--g-text-subheader-2-font-size); - font-weight: var(--g-text-subheader-font-weight); - fill: var(--g-color-text-primary); -} - -.chartkit-d3-plot-title { - font-size: var(--g-text-subheader-3-font-size); - font-weight: var(--g-text-subheader-font-weight); - fill: var(--g-color-text-secondary); -} - -.chartkit-d3-tooltip { - &[class] { - --g-popup-border-width: 0; - pointer-events: none; - - > div { - animation-duration: unset; - animation-timing-function: unset; - animation-fill-mode: unset; - } - } - - &__content { - padding: 10px 14px; - background-color: var(--g-color-infographics-tooltip-bg); - border: 1px solid var(--g-color-line-generic); - border-radius: 3px; - box-shadow: 0 2px 12px var(--g-color-sfx-shadow); - text-wrap: nowrap; - } - - &__content-row { - display: flex; - align-items: center; - } - - &__color { - height: 8px; - width: 16px; - display: inline-block; - margin-right: 8px; - border-radius: 2px; - background-color: #dddddd; - } -} diff --git a/src/plugins/d3/renderer/constants/defaults/axis.ts b/src/plugins/d3/renderer/constants/defaults/axis.ts deleted file mode 100644 index 8cd0ae28..00000000 --- a/src/plugins/d3/renderer/constants/defaults/axis.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type {BaseTextStyle, ChartKitWidgetAxis, ChartKitWidgetAxisType} from '../../../../../types'; - -export const axisLabelsDefaults = { - margin: 10, - padding: 10, - fontSize: 11, - maxWidth: 80, -}; - -type AxisTitleDefaults = Required & { - style: BaseTextStyle; -}; - -const axisTitleDefaults: AxisTitleDefaults = { - text: '', - margin: 0, - style: { - fontSize: '14px', - }, - align: 'center', - maxRowCount: 1, -}; - -export const xAxisTitleDefaults: AxisTitleDefaults = { - ...axisTitleDefaults, - margin: 4, -}; - -export const yAxisTitleDefaults: AxisTitleDefaults = { - ...axisTitleDefaults, - margin: 8, -}; - -export const DEFAULT_AXIS_TYPE: ChartKitWidgetAxisType = 'linear'; diff --git a/src/plugins/d3/renderer/constants/defaults/index.ts b/src/plugins/d3/renderer/constants/defaults/index.ts deleted file mode 100644 index 7dfc56d3..00000000 --- a/src/plugins/d3/renderer/constants/defaults/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './axis'; -export * from './legend'; -export * from './series-options'; diff --git a/src/plugins/d3/renderer/constants/defaults/legend.ts b/src/plugins/d3/renderer/constants/defaults/legend.ts deleted file mode 100644 index f3cc0ee1..00000000 --- a/src/plugins/d3/renderer/constants/defaults/legend.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type {ChartKitWidgetLegend} from '../../../../../types'; - -export const legendDefaults = { - align: 'center' as Required['align'], - itemDistance: 20, - margin: 15, - itemStyle: { - fontSize: '12px', - }, -}; - -export const CONTINUOUS_LEGEND_SIZE = { - height: 12, - width: 200, -}; diff --git a/src/plugins/d3/renderer/constants/defaults/series-options.ts b/src/plugins/d3/renderer/constants/defaults/series-options.ts deleted file mode 100644 index 71467381..00000000 --- a/src/plugins/d3/renderer/constants/defaults/series-options.ts +++ /dev/null @@ -1,125 +0,0 @@ -import type {ChartKitWidgetSeriesOptions} from '../../../../../types'; - -type DefaultBarXSeriesOptions = Partial & { - 'bar-x': {barMaxWidth: number; barPadding: number; groupPadding: number}; -}; - -type DefaultBarYSeriesOptions = Partial & { - 'bar-y': {barMaxWidth: number; barPadding: number; groupPadding: number}; -}; - -type DefaultWaterfallSeriesOptions = Partial & { - waterfall: {barMaxWidth: number; barPadding: number}; -}; - -export type SeriesOptionsDefaults = Partial & - DefaultBarXSeriesOptions & - DefaultBarYSeriesOptions & - DefaultWaterfallSeriesOptions; - -export const seriesOptionsDefaults: SeriesOptionsDefaults = { - 'bar-x': { - barMaxWidth: 50, - barPadding: 0.1, - groupPadding: 0.2, - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - 'bar-y': { - barMaxWidth: 50, - barPadding: 0.1, - groupPadding: 0.2, - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - pie: { - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - scatter: { - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - line: { - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - area: { - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - treemap: { - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, - waterfall: { - barMaxWidth: 50, - barPadding: 0.1, - states: { - hover: { - enabled: true, - brightness: 0.3, - }, - inactive: { - enabled: false, - opacity: 0.5, - }, - }, - }, -}; diff --git a/src/plugins/d3/renderer/constants/index.ts b/src/plugins/d3/renderer/constants/index.ts deleted file mode 100644 index 1c995d20..00000000 --- a/src/plugins/d3/renderer/constants/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -export * from './defaults'; - -export const DEFAULT_PALETTE = [ - '#4DA2F1', - '#FF3D64', - '#8AD554', - '#FFC636', - '#FFB9DD', - '#84D1EE', - '#FF91A1', - '#54A520', - '#DB9100', - '#BA74B3', - '#1F68A9', - '#ED65A9', - '#0FA08D', - '#FF7E00', - '#E8B0A4', - '#52A6C5', - '#BE2443', - '#70C1AF', - '#FFB46C', - '#DCA3D7', -]; - -export const DEFAULT_AXIS_LABEL_FONT_SIZE = '11px'; diff --git a/src/plugins/d3/renderer/d3-dispatcher.ts b/src/plugins/d3/renderer/d3-dispatcher.ts deleted file mode 100644 index 91ae411e..00000000 --- a/src/plugins/d3/renderer/d3-dispatcher.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {dispatch} from 'd3'; - -export const getD3Dispatcher = () => { - return dispatch('hover-shape', 'click-chart'); -}; diff --git a/src/plugins/d3/renderer/hooks/index.ts b/src/plugins/d3/renderer/hooks/index.ts deleted file mode 100644 index 6600b60c..00000000 --- a/src/plugins/d3/renderer/hooks/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './useChartDimensions'; -export * from './useChartOptions'; -export * from './useChartOptions/types'; -export * from './useAxisScales'; -export * from './useSeries'; -export * from './useSeries/types'; -export * from './useShapes'; -export * from './useTooltip'; -export * from './useTooltip/types'; -export * from './useSplit/types'; diff --git a/src/plugins/d3/renderer/hooks/useAxisScales/index.ts b/src/plugins/d3/renderer/hooks/useAxisScales/index.ts deleted file mode 100644 index 2fcab444..00000000 --- a/src/plugins/d3/renderer/hooks/useAxisScales/index.ts +++ /dev/null @@ -1,270 +0,0 @@ -import React from 'react'; - -import {extent, scaleBand, scaleLinear, scaleLog, scaleUtc} from 'd3'; -import type {ScaleBand, ScaleLinear, ScaleTime} from 'd3'; -import get from 'lodash/get'; - -import { - ChartKitWidgetAxis, - ChartKitWidgetAxisType, - ChartKitWidgetSeries, -} from '../../../../../types'; -import {DEFAULT_AXIS_TYPE} from '../../constants'; -import { - CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, - getAxisHeight, - getDataCategoryValue, - getDefaultMaxXAxisValue, - getDomainDataXBySeries, - getDomainDataYBySeries, - getOnlyVisibleSeries, - isAxisRelatedSeries, - isSeriesWithCategoryValues, -} from '../../utils'; -import type {AxisDirection} from '../../utils'; -import type {PreparedAxis} from '../useChartOptions/types'; -import type {PreparedSeries} from '../useSeries/types'; -import type {PreparedSplit} from '../useSplit/types'; - -export type ChartScale = - | ScaleLinear - | ScaleBand - | ScaleTime; - -type Args = { - boundsWidth: number; - boundsHeight: number; - series: PreparedSeries[]; - xAxis: PreparedAxis; - yAxis: PreparedAxis[]; - split: PreparedSplit; -}; - -type ReturnValue = { - xScale?: ChartScale; - yScale?: ChartScale[]; -}; - -const isNumericalArrayData = (data: unknown[]): data is number[] => { - return data.every((d) => typeof d === 'number' || d === null); -}; - -const filterCategoriesByVisibleSeries = (args: { - axisDirection: AxisDirection; - categories: string[]; - series: (PreparedSeries | ChartKitWidgetSeries)[]; -}) => { - const {axisDirection, categories, series} = args; - - const visibleCategories = new Set(); - series.forEach((s) => { - if (isSeriesWithCategoryValues(s)) { - s.data.forEach((d) => { - visibleCategories.add(getDataCategoryValue({axisDirection, categories, data: d})); - }); - } - }); - - return categories.filter((c) => visibleCategories.has(c)); -}; - -export function createYScale(axis: PreparedAxis, series: PreparedSeries[], boundsHeight: number) { - const yType: ChartKitWidgetAxisType = get(axis, 'type', DEFAULT_AXIS_TYPE); - const yMin = get(axis, 'min'); - const yCategories = get(axis, 'categories'); - const yTimestamps = get(axis, 'timestamps'); - - switch (yType) { - case 'linear': - case 'logarithmic': { - const domain = getDomainDataYBySeries(series); - const range = [boundsHeight, boundsHeight * axis.maxPadding]; - - if (isNumericalArrayData(domain)) { - const [domainYMin, domainMax] = extent(domain) as [number, number]; - const yMinValue = typeof yMin === 'number' ? yMin : domainYMin; - let yMaxValue = domainMax; - if (series.some((s) => CHART_SERIES_WITH_VOLUME_ON_Y_AXIS.includes(s.type))) { - yMaxValue = Math.max(yMaxValue, 0); - } - - const scaleFn = yType === 'logarithmic' ? scaleLog : scaleLinear; - return scaleFn().domain([yMinValue, yMaxValue]).range(range).nice(); - } - - break; - } - case 'category': { - if (yCategories) { - const filteredCategories = filterCategoriesByVisibleSeries({ - axisDirection: 'y', - categories: yCategories, - series: series, - }); - return scaleBand().domain(filteredCategories).range([boundsHeight, 0]); - } - - break; - } - case 'datetime': { - const range = [boundsHeight, boundsHeight * axis.maxPadding]; - - if (yTimestamps) { - const [yMin, yMax] = extent(yTimestamps) as [number, number]; - return scaleUtc().domain([yMin, yMax]).range(range).nice(); - } else { - const domain = getDomainDataYBySeries(series); - - if (isNumericalArrayData(domain)) { - const [yMin, yMax] = extent(domain) as [number, number]; - return scaleUtc().domain([yMin, yMax]).range(range).nice(); - } - } - - break; - } - } - - throw new Error('Failed to create yScale'); -} - -function calculateXAxisPadding(series: (PreparedSeries | ChartKitWidgetSeries)[]) { - let result = 0; - - series.forEach((s) => { - switch (s.type) { - case 'bar-y': { - // Since labels can be located to the right of the bar, need to add an additional space - const inside = get(s, 'dataLabels.inside'); - if (!inside) { - const labelsMaxWidth = get(s, 'dataLabels.maxWidth', 0); - result = Math.max(result, labelsMaxWidth); - } - - break; - } - } - }); - - return result; -} - -export function createXScale( - axis: PreparedAxis | ChartKitWidgetAxis, - series: (PreparedSeries | ChartKitWidgetSeries)[], - boundsWidth: number, -) { - const xMin = get(axis, 'min'); - const xMax = getDefaultMaxXAxisValue(series); - const xType: ChartKitWidgetAxisType = get(axis, 'type', DEFAULT_AXIS_TYPE); - const xCategories = get(axis, 'categories'); - const xTimestamps = get(axis, 'timestamps'); - const maxPadding = get(axis, 'maxPadding', 0); - - const xAxisMinPadding = boundsWidth * maxPadding + calculateXAxisPadding(series); - const xRange = [0, boundsWidth - xAxisMinPadding]; - - switch (xType) { - case 'linear': - case 'logarithmic': { - const domain = getDomainDataXBySeries(series); - - if (isNumericalArrayData(domain)) { - const [domainXMin, domainXMax] = extent(domain) as [number, number]; - const xMinValue = typeof xMin === 'number' ? xMin : domainXMin; - const xMaxValue = - typeof xMax === 'number' ? Math.max(xMax, domainXMax) : domainXMax; - - const scaleFn = xType === 'logarithmic' ? scaleLog : scaleLinear; - return scaleFn().domain([xMinValue, xMaxValue]).range(xRange).nice(); - } - - break; - } - case 'category': { - if (xCategories) { - const filteredCategories = filterCategoriesByVisibleSeries({ - axisDirection: 'x', - categories: xCategories, - series: series, - }); - const xScale = scaleBand().domain(filteredCategories).range([0, boundsWidth]); - - if (xScale.step() / 2 < xAxisMinPadding) { - xScale.range(xRange); - } - - return xScale; - } - - break; - } - case 'datetime': { - if (xTimestamps) { - const [xMin, xMax] = extent(xTimestamps) as [number, number]; - return scaleUtc().domain([xMin, xMax]).range(xRange).nice(); - } else { - const domain = getDomainDataXBySeries(series); - - if (isNumericalArrayData(domain)) { - const [xMin, xMax] = extent(domain) as [number, number]; - return scaleUtc().domain([xMin, xMax]).range(xRange).nice(); - } - } - - break; - } - } - - throw new Error('Failed to create xScale'); -} - -const createScales = (args: Args) => { - const {boundsWidth, boundsHeight, series, xAxis, yAxis, split} = args; - let visibleSeries = getOnlyVisibleSeries(series); - // Reassign to all series in case of all series unselected, - // otherwise we will get an empty space without grid - visibleSeries = visibleSeries.length === 0 ? series : visibleSeries; - - return { - xScale: createXScale(xAxis, visibleSeries, boundsWidth), - yScale: yAxis.map((axis, index) => { - const axisSeries = series.filter((s) => { - const seriesAxisIndex = get(s, 'yAxis', 0); - return seriesAxisIndex === index; - }); - const visibleAxisSeries = getOnlyVisibleSeries(axisSeries); - const axisHeight = getAxisHeight({boundsHeight, split}); - return createYScale( - axis, - visibleAxisSeries.length ? visibleAxisSeries : axisSeries, - axisHeight, - ); - }), - }; -}; - -/** - * Uses to create scales for axis related series - */ -export const useAxisScales = (args: Args): ReturnValue => { - const {boundsWidth, boundsHeight, series, xAxis, yAxis, split} = args; - return React.useMemo(() => { - let xScale: ChartScale | undefined; - let yScale: ChartScale[] | undefined; - const hasAxisRelatedSeries = series.some(isAxisRelatedSeries); - - if (hasAxisRelatedSeries) { - ({xScale, yScale} = createScales({ - boundsWidth, - boundsHeight, - series, - xAxis, - yAxis, - split, - })); - } - - return {xScale, yScale}; - }, [boundsWidth, boundsHeight, series, xAxis, yAxis, split]); -}; diff --git a/src/plugins/d3/renderer/hooks/useChartDimensions/index.ts b/src/plugins/d3/renderer/hooks/useChartDimensions/index.ts deleted file mode 100644 index d45c61dd..00000000 --- a/src/plugins/d3/renderer/hooks/useChartDimensions/index.ts +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; - -import type {ChartMargin} from '../../../../../types'; -import type {PreparedAxis, PreparedLegend, PreparedSeries} from '../../hooks'; -import {isAxisRelatedSeries} from '../../utils'; - -import {getBoundsWidth} from './utils'; - -export {getBoundsWidth} from './utils'; - -type Args = { - width: number; - height: number; - margin: ChartMargin; - preparedLegend: PreparedLegend; - preparedXAxis: PreparedAxis; - preparedYAxis: PreparedAxis[]; - preparedSeries: PreparedSeries[]; -}; - -const getBottomOffset = (args: { - hasAxisRelatedSeries: boolean; - preparedLegend: PreparedLegend; - preparedXAxis: PreparedAxis; -}) => { - const {hasAxisRelatedSeries, preparedLegend, preparedXAxis} = args; - let result = 0; - - if (preparedLegend.enabled) { - result += preparedLegend.height + preparedLegend.margin; - } - - if (hasAxisRelatedSeries) { - if (preparedXAxis.title.text) { - result += preparedXAxis.title.height + preparedXAxis.title.margin; - } - - if (preparedXAxis.labels.enabled) { - result += preparedXAxis.labels.margin + preparedXAxis.labels.height; - } - } - - return result; -}; - -export const useChartDimensions = (args: Args) => { - const {margin, width, height, preparedLegend, preparedXAxis, preparedYAxis, preparedSeries} = - args; - - return React.useMemo(() => { - const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries); - const boundsWidth = getBoundsWidth({chartWidth: width, chartMargin: margin, preparedYAxis}); - const bottomOffset = getBottomOffset({ - hasAxisRelatedSeries, - preparedLegend, - preparedXAxis, - }); - - const boundsHeight = height - margin.top - margin.bottom - bottomOffset; - - return {boundsWidth, boundsHeight}; - }, [margin, width, height, preparedLegend, preparedXAxis, preparedYAxis, preparedSeries]); -}; diff --git a/src/plugins/d3/renderer/hooks/useChartDimensions/utils.ts b/src/plugins/d3/renderer/hooks/useChartDimensions/utils.ts deleted file mode 100644 index b1a5ff2d..00000000 --- a/src/plugins/d3/renderer/hooks/useChartDimensions/utils.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type {PreparedAxis, PreparedChart} from '../../hooks'; - -export const getBoundsWidth = (args: { - chartWidth: number; - chartMargin: PreparedChart['margin']; - preparedYAxis: PreparedAxis[]; -}) => { - const {chartWidth, chartMargin, preparedYAxis} = args; - - return ( - chartWidth - - chartMargin.right - - chartMargin.left - - getWidthOccupiedByYAxis({preparedAxis: preparedYAxis}) - ); -}; - -export function getYAxisWidth(axis: PreparedAxis | undefined) { - let result = 0; - if (axis?.title.text) { - result += axis.title.height + axis.title.margin; - } - - if (axis?.labels.enabled) { - result += axis.labels.margin + axis.labels.width; - } - - return result; -} - -export function getWidthOccupiedByYAxis(args: {preparedAxis: PreparedAxis[]}) { - const {preparedAxis} = args; - let leftAxisWidth = 0; - let rightAxisWidth = 0; - - preparedAxis?.forEach((axis) => { - const axisWidth = getYAxisWidth(axis); - if (axis.position === 'right') { - rightAxisWidth = Math.max(rightAxisWidth, axisWidth); - } else { - leftAxisWidth = Math.max(leftAxisWidth, axisWidth); - } - }); - - return leftAxisWidth + rightAxisWidth; -} diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/chart.ts b/src/plugins/d3/renderer/hooks/useChartOptions/chart.ts deleted file mode 100644 index 8b71051f..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/chart.ts +++ /dev/null @@ -1,45 +0,0 @@ -import get from 'lodash/get'; - -import type {ChartKitWidgetData} from '../../../../../types'; - -import type {PreparedChart, PreparedTitle} from './types'; - -const getMarginTop = (args: { - chart: ChartKitWidgetData['chart']; - preparedTitle?: PreparedTitle; -}) => { - const {chart, preparedTitle} = args; - let marginTop = get(chart, 'margin.top', 0); - - if (preparedTitle?.height) { - marginTop += preparedTitle.height; - } - - return marginTop; -}; - -const getMarginRight = (args: {chart: ChartKitWidgetData['chart']}) => { - const {chart} = args; - - return get(chart, 'margin.right', 0); -}; - -export const getPreparedChart = (args: { - chart: ChartKitWidgetData['chart']; - preparedTitle?: PreparedTitle; -}): PreparedChart => { - const {chart, preparedTitle} = args; - const marginTop = getMarginTop({chart, preparedTitle}); - const marginBottom = get(chart, 'margin.bottom', 0); - const marginLeft = get(chart, 'margin.left', 0); - const marginRight = getMarginRight({chart}); - - return { - margin: { - top: marginTop, - right: marginRight, - bottom: marginBottom, - left: marginLeft, - }, - }; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/index.ts b/src/plugins/d3/renderer/hooks/useChartOptions/index.ts deleted file mode 100644 index e4105b37..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; - -import type {ChartKitWidgetData} from '../../../../../types'; - -import {getPreparedChart} from './chart'; -import {getPreparedTitle} from './title'; -import {getPreparedTooltip} from './tooltip'; -import type {ChartOptions} from './types'; - -type Args = { - data: ChartKitWidgetData; -}; - -export const useChartOptions = (args: Args): ChartOptions => { - const { - data: {chart, title, tooltip}, - } = args; - const options: ChartOptions = React.useMemo(() => { - const preparedTitle = getPreparedTitle({title}); - const preparedTooltip = getPreparedTooltip({tooltip}); - - const preparedChart = getPreparedChart({ - chart, - preparedTitle, - }); - return { - chart: preparedChart, - title: preparedTitle, - tooltip: preparedTooltip, - }; - }, [chart, title, tooltip]); - - return options; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/title.ts b/src/plugins/d3/renderer/hooks/useChartOptions/title.ts deleted file mode 100644 index abbac7ee..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/title.ts +++ /dev/null @@ -1,29 +0,0 @@ -import get from 'lodash/get'; - -import type {BaseTextStyle, ChartKitWidgetData} from '../../../../../types'; -import {getHorisontalSvgTextHeight} from '../../utils'; - -import type {PreparedTitle} from './types'; - -const DEFAULT_TITLE_FONT_SIZE = '15px'; -const TITLE_PADDINGS = 8 * 2; - -export const getPreparedTitle = ({ - title, -}: { - title: ChartKitWidgetData['title']; -}): PreparedTitle | undefined => { - const titleText = get(title, 'text'); - const titleStyle: BaseTextStyle = { - fontSize: get(title, 'style.fontSize', DEFAULT_TITLE_FONT_SIZE), - fontWeight: get(title, 'style.fontWeight'), - }; - const titleHeight = titleText - ? getHorisontalSvgTextHeight({text: titleText, style: titleStyle}) + TITLE_PADDINGS - : 0; - const preparedTitle: PreparedTitle | undefined = titleText - ? {text: titleText, style: titleStyle, height: titleHeight} - : undefined; - - return preparedTitle; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/tooltip.ts b/src/plugins/d3/renderer/hooks/useChartOptions/tooltip.ts deleted file mode 100644 index 54e1140f..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/tooltip.ts +++ /dev/null @@ -1,16 +0,0 @@ -import get from 'lodash/get'; - -import type {ChartKitWidgetData} from '../../../../../types/widget-data'; - -import type {PreparedTooltip} from './types'; - -export const getPreparedTooltip = (args: { - tooltip: ChartKitWidgetData['tooltip']; -}): PreparedTooltip => { - const {tooltip} = args; - - return { - ...tooltip, - enabled: get(tooltip, 'enabled', true), - }; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/types.ts b/src/plugins/d3/renderer/hooks/useChartOptions/types.ts deleted file mode 100644 index b8a54ffc..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/types.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { - BaseTextStyle, - ChartKitWidgetAxis, - ChartKitWidgetAxisLabels, - ChartKitWidgetAxisTitleAlignment, - ChartKitWidgetAxisType, - ChartKitWidgetData, - ChartMargin, -} from '../../../../../types'; - -type PreparedAxisLabels = Omit< - ChartKitWidgetAxisLabels, - 'enabled' | 'padding' | 'style' | 'autoRotation' -> & - Required> & { - style: BaseTextStyle; - rotation: number; - height: number; - width: number; - lineHeight: number; - maxWidth: number; - }; - -export type PreparedChart = { - margin: ChartMargin; -}; - -export type PreparedAxis = Omit & { - type: ChartKitWidgetAxisType; - labels: PreparedAxisLabels; - title: { - height: number; - width: number; - text: string; - margin: number; - style: BaseTextStyle; - align: ChartKitWidgetAxisTitleAlignment; - maxRowCount: number; - }; - min?: number; - grid: { - enabled: boolean; - }; - maxPadding: number; - ticks: { - pixelInterval?: number; - }; - position: 'left' | 'right' | 'top' | 'bottom'; - plotIndex: number; -}; - -export type PreparedTitle = ChartKitWidgetData['title'] & { - height: number; -}; - -export type PreparedTooltip = ChartKitWidgetData['tooltip'] & { - enabled: boolean; -}; - -export type ChartOptions = { - chart: PreparedChart; - tooltip: PreparedTooltip; - title?: PreparedTitle; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/x-axis.ts b/src/plugins/d3/renderer/hooks/useChartOptions/x-axis.ts deleted file mode 100644 index 10767a02..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/x-axis.ts +++ /dev/null @@ -1,168 +0,0 @@ -import type {AxisDomain, AxisScale} from 'd3'; -import get from 'lodash/get'; - -import type {BaseTextStyle, ChartKitWidgetSeries, ChartKitWidgetXAxis} from '../../../../../types'; -import { - DEFAULT_AXIS_LABEL_FONT_SIZE, - axisLabelsDefaults, - xAxisTitleDefaults, -} from '../../constants'; -import { - CHART_SERIES_WITH_VOLUME_ON_X_AXIS, - calculateCos, - formatAxisTickLabel, - getClosestPointsRange, - getHorisontalSvgTextHeight, - getLabelsSize, - getMaxTickCount, - getTicksCount, - getXAxisItems, - hasOverlappingLabels, - wrapText, -} from '../../utils'; -import {createXScale} from '../useAxisScales'; - -import type {PreparedAxis} from './types'; - -function getLabelSettings({ - axis, - series, - width, - autoRotation = true, -}: { - axis: PreparedAxis; - series: ChartKitWidgetSeries[]; - width: number; - autoRotation?: boolean; -}) { - const scale = createXScale(axis, series, width); - const tickCount = getTicksCount({axis, range: width}); - const ticks = getXAxisItems({ - scale: scale as AxisScale, - count: tickCount, - maxCount: getMaxTickCount({width, axis}), - }); - const step = getClosestPointsRange(axis, ticks); - const labels = ticks.map((value: AxisDomain) => { - return formatAxisTickLabel({ - axis, - value, - step, - }); - }); - const overlapping = hasOverlappingLabels({ - width, - labels, - padding: axis.labels.padding, - style: axis.labels.style, - }); - - const defaultRotation = overlapping && autoRotation ? -45 : 0; - const rotation = axis.labels.rotation || defaultRotation; - const labelsHeight = rotation - ? getLabelsSize({ - labels, - style: axis.labels.style, - rotation, - }).maxHeight - : axis.labels.lineHeight; - const maxHeight = rotation ? calculateCos(rotation) * axis.labels.maxWidth : labelsHeight; - - return {height: Math.min(maxHeight, labelsHeight), rotation}; -} - -function getAxisMin(axis?: ChartKitWidgetXAxis, series?: ChartKitWidgetSeries[]) { - const min = axis?.min; - - if ( - typeof min === 'undefined' && - series?.some((s) => CHART_SERIES_WITH_VOLUME_ON_X_AXIS.includes(s.type)) - ) { - return series.reduce((minValue, s) => { - const minYValue = s.data.reduce((res, d) => Math.min(res, get(d, 'x', 0)), 0); - return Math.min(minValue, minYValue); - }, 0); - } - - return min; -} - -export const getPreparedXAxis = ({ - xAxis, - series, - width, -}: { - xAxis?: ChartKitWidgetXAxis; - series: ChartKitWidgetSeries[]; - width: number; -}): PreparedAxis => { - const titleText = get(xAxis, 'title.text', ''); - const titleStyle: BaseTextStyle = { - ...xAxisTitleDefaults.style, - ...get(xAxis, 'title.style'), - }; - const titleMaxRowsCount = get(xAxis, 'title.maxRowCount', xAxisTitleDefaults.maxRowCount); - const estimatedTitleRows = wrapText({ - text: titleText, - style: titleStyle, - width, - }).slice(0, titleMaxRowsCount); - const titleSize = getLabelsSize({ - labels: [titleText], - style: titleStyle, - }); - const labelsStyle = { - fontSize: get(xAxis, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE), - }; - - const preparedXAxis: PreparedAxis = { - type: get(xAxis, 'type', 'linear'), - labels: { - enabled: get(xAxis, 'labels.enabled', true), - margin: get(xAxis, 'labels.margin', axisLabelsDefaults.margin), - padding: get(xAxis, 'labels.padding', axisLabelsDefaults.padding), - dateFormat: get(xAxis, 'labels.dateFormat'), - numberFormat: get(xAxis, 'labels.numberFormat'), - rotation: get(xAxis, 'labels.rotation', 0), - style: labelsStyle, - width: 0, - height: 0, - lineHeight: getHorisontalSvgTextHeight({text: 'Tmp', style: labelsStyle}), - maxWidth: get(xAxis, 'labels.maxWidth', axisLabelsDefaults.maxWidth), - }, - lineColor: get(xAxis, 'lineColor'), - categories: get(xAxis, 'categories'), - timestamps: get(xAxis, 'timestamps'), - title: { - text: titleText, - style: titleStyle, - margin: get(xAxis, 'title.margin', xAxisTitleDefaults.margin), - height: titleSize.maxHeight * estimatedTitleRows.length, - width: titleSize.maxWidth, - align: get(xAxis, 'title.align', xAxisTitleDefaults.align), - maxRowCount: get(xAxis, 'title.maxRowCount', xAxisTitleDefaults.maxRowCount), - }, - min: getAxisMin(xAxis, series), - maxPadding: get(xAxis, 'maxPadding', 0.01), - grid: { - enabled: get(xAxis, 'grid.enabled', true), - }, - ticks: { - pixelInterval: get(xAxis, 'ticks.pixelInterval'), - }, - position: 'bottom', - plotIndex: 0, - }; - - const {height, rotation} = getLabelSettings({ - axis: preparedXAxis, - series, - width, - autoRotation: xAxis?.labels?.autoRotation, - }); - - preparedXAxis.labels.height = height; - preparedXAxis.labels.rotation = rotation; - - return preparedXAxis; -}; diff --git a/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts b/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts deleted file mode 100644 index fa585ce2..00000000 --- a/src/plugins/d3/renderer/hooks/useChartOptions/y-axis.ts +++ /dev/null @@ -1,176 +0,0 @@ -import type {AxisDomain, AxisScale} from 'd3'; -import get from 'lodash/get'; - -import type {BaseTextStyle, ChartKitWidgetSeries, ChartKitWidgetYAxis} from '../../../../../types'; -import { - DEFAULT_AXIS_LABEL_FONT_SIZE, - DEFAULT_AXIS_TYPE, - axisLabelsDefaults, - yAxisTitleDefaults, -} from '../../constants'; -import { - CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, - formatAxisTickLabel, - getClosestPointsRange, - getHorisontalSvgTextHeight, - getLabelsSize, - getScaleTicks, - getWaterfallPointSubtotal, - wrapText, -} from '../../utils'; -import {createYScale} from '../useAxisScales'; -import type {PreparedSeries, PreparedWaterfallSeries} from '../useSeries/types'; - -import type {PreparedAxis} from './types'; - -const getAxisLabelMaxWidth = (args: {axis: PreparedAxis; series: ChartKitWidgetSeries[]}) => { - const {axis, series} = args; - - if (!axis.labels.enabled) { - return 0; - } - - const scale = createYScale(axis, series as PreparedSeries[], 1); - const ticks: AxisDomain[] = getScaleTicks(scale as AxisScale); - - // FIXME: it is necessary to filter data, since we do not draw overlapping ticks - - const step = getClosestPointsRange(axis, ticks); - const labels = (ticks as (string | number)[]).map((tick) => - formatAxisTickLabel({ - axis, - value: tick, - step, - }), - ); - - return getLabelsSize({ - labels, - style: axis.labels.style, - rotation: axis.labels.rotation, - }).maxWidth; -}; - -function getAxisMin(axis?: ChartKitWidgetYAxis, series?: ChartKitWidgetSeries[]) { - const min = axis?.min; - - if ( - typeof min === 'undefined' && - series?.some((s) => CHART_SERIES_WITH_VOLUME_ON_Y_AXIS.includes(s.type)) - ) { - return series.reduce((minValue, s) => { - switch (s.type) { - case 'waterfall': { - const minSubTotal = s.data.reduce( - (res, d) => - Math.min( - res, - getWaterfallPointSubtotal(d, s as PreparedWaterfallSeries) || 0, - ), - 0, - ); - return Math.min(minValue, minSubTotal); - } - default: { - const minYValue = s.data.reduce((res, d) => Math.min(res, get(d, 'y', 0)), 0); - return Math.min(minValue, minYValue); - } - } - }, 0); - } - - return min; -} - -export const getPreparedYAxis = ({ - series, - yAxis, - height, -}: { - series: ChartKitWidgetSeries[]; - yAxis: ChartKitWidgetYAxis[] | undefined; - height: number; -}): PreparedAxis[] => { - const axisByPlot: ChartKitWidgetYAxis[][] = []; - const axisItems = yAxis || [{} as ChartKitWidgetYAxis]; - return axisItems.map((axisItem) => { - const plotIndex = get(axisItem, 'plotIndex', 0); - const firstPlotAxis = !axisByPlot[plotIndex]; - if (firstPlotAxis) { - axisByPlot[plotIndex] = []; - } - axisByPlot[plotIndex].push(axisItem); - const defaultAxisPosition = firstPlotAxis ? 'left' : 'right'; - - const labelsEnabled = get(axisItem, 'labels.enabled', true); - - const labelsStyle: BaseTextStyle = { - fontSize: get(axisItem, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE), - }; - const titleText = get(axisItem, 'title.text', ''); - const titleStyle = { - ...yAxisTitleDefaults.style, - ...get(axisItem, 'title.style'), - }; - const titleMaxRowsCount = get( - axisItem, - 'title.maxRowCount', - yAxisTitleDefaults.maxRowCount, - ); - const estimatedTitleRows = wrapText({ - text: titleText, - style: titleStyle, - width: height, - }).slice(0, titleMaxRowsCount); - const titleSize = getLabelsSize({labels: [titleText], style: titleStyle}); - const axisType = get(axisItem, 'type', DEFAULT_AXIS_TYPE); - const preparedAxis: PreparedAxis = { - type: axisType, - labels: { - enabled: labelsEnabled, - margin: labelsEnabled - ? get(axisItem, 'labels.margin', axisLabelsDefaults.margin) - : 0, - padding: labelsEnabled - ? get(axisItem, 'labels.padding', axisLabelsDefaults.padding) - : 0, - dateFormat: get(axisItem, 'labels.dateFormat'), - numberFormat: get(axisItem, 'labels.numberFormat'), - style: labelsStyle, - rotation: get(axisItem, 'labels.rotation', 0), - width: 0, - height: 0, - lineHeight: getHorisontalSvgTextHeight({text: 'TmpLabel', style: labelsStyle}), - maxWidth: get(axisItem, 'labels.maxWidth', axisLabelsDefaults.maxWidth), - }, - lineColor: get(axisItem, 'lineColor'), - categories: get(axisItem, 'categories'), - timestamps: get(axisItem, 'timestamps'), - title: { - text: titleText, - margin: get(axisItem, 'title.margin', yAxisTitleDefaults.margin), - style: titleStyle, - width: titleSize.maxWidth, - height: titleSize.maxHeight * estimatedTitleRows.length, - align: get(axisItem, 'title.align', yAxisTitleDefaults.align), - maxRowCount: titleMaxRowsCount, - }, - min: getAxisMin(axisItem, series), - maxPadding: get(axisItem, 'maxPadding', 0.05), - grid: { - enabled: get(axisItem, 'grid.enabled', firstPlotAxis), - }, - ticks: { - pixelInterval: get(axisItem, 'ticks.pixelInterval'), - }, - position: get(axisItem, 'position', defaultAxisPosition), - plotIndex: get(axisItem, 'plotIndex', 0), - }; - - if (labelsEnabled) { - preparedAxis.labels.width = getAxisLabelMaxWidth({axis: preparedAxis, series}); - } - - return preparedAxis; - }); -}; diff --git a/src/plugins/d3/renderer/hooks/useSeries/__tests__/prepare-line-series.test.ts b/src/plugins/d3/renderer/hooks/useSeries/__tests__/prepare-line-series.test.ts deleted file mode 100644 index adb398ad..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/__tests__/prepare-line-series.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import {scaleOrdinal} from 'd3'; - -import type {LineSeries} from '../../../../../../types'; -import {DEFAULT_PALETTE} from '../../../constants'; -import {DEFAULT_MARKER, prepareLineSeries} from '../prepare-line'; -import type {PreparedLegend} from '../types'; - -describe('prepareLineSeries', () => { - describe('marker', () => { - const commonArgs = { - colorScale: scaleOrdinal([] as string[], DEFAULT_PALETTE), - legend: {} as PreparedLegend, - }; - - it('If the marker parameters are not specified, the default values should be applied', () => { - const preparedSeries = prepareLineSeries({ - ...commonArgs, - series: [{}] as LineSeries[], - }); - - const actual = preparedSeries.map((s) => s.marker.states.normal); - const expected = [DEFAULT_MARKER]; - - expect(actual).toEqual(expected); - }); - - it('Normal state. The settings of a specific series should be prioritized over the seriesOptions', () => { - const preparedSeries = prepareLineSeries({ - ...commonArgs, - seriesOptions: { - line: { - marker: { - enabled: true, - radius: 100, - symbol: 'square', - }, - }, - }, - series: [ - {}, - { - marker: { - radius: 200, - symbol: 'circle', - }, - }, - {marker: {enabled: false}}, - ] as LineSeries[], - }); - - const actual = preparedSeries.map((s) => s.marker.states.normal); - const expected = [ - {enabled: true, radius: 100, symbol: 'square', borderColor: '', borderWidth: 0}, - {enabled: true, radius: 200, symbol: 'circle', borderColor: '', borderWidth: 0}, - {enabled: false, radius: 100, symbol: 'square', borderColor: '', borderWidth: 0}, - ]; - - expect(actual).toEqual(expected); - }); - }); -}); diff --git a/src/plugins/d3/renderer/hooks/useSeries/constants.ts b/src/plugins/d3/renderer/hooks/useSeries/constants.ts deleted file mode 100644 index 8996bb37..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/constants.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type {BaseTextStyle, Halo} from '../../../../../types'; -import {PointMarkerOptions} from '../../../../../types/widget-data/marker'; - -export const DEFAULT_LEGEND_SYMBOL_SIZE = 8; - -export const DEFAULT_LEGEND_SYMBOL_PADDING = 5; - -export const DEFAULT_DATALABELS_PADDING = 5; - -export const DEFAULT_DATALABELS_STYLE: BaseTextStyle = { - fontSize: '11px', - fontWeight: 'bold', - fontColor: 'var(--d3-data-labels)', -}; - -export const DEFAULT_HALO_OPTIONS: Required = { - enabled: true, - opacity: 0.25, - size: 6, -}; - -export const DEFAULT_POINT_MARKER_OPTIONS: Omit, 'enabled'> = { - radius: 4, - borderColor: '', - borderWidth: 0, - symbol: 'circle', -}; diff --git a/src/plugins/d3/renderer/hooks/useSeries/index.ts b/src/plugins/d3/renderer/hooks/useSeries/index.ts deleted file mode 100644 index 4f17b033..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -import React from 'react'; - -import {group, scaleOrdinal} from 'd3'; - -import type {ChartKitWidgetData} from '../../../../../types'; -import {DEFAULT_PALETTE} from '../../constants'; -import {getSeriesNames} from '../../utils'; -import type {PreparedAxis, PreparedChart} from '../useChartOptions/types'; - -import {getLegendComponents, getPreparedLegend} from './prepare-legend'; -import {getPreparedOptions} from './prepare-options'; -import {prepareSeries} from './prepareSeries'; -import type {OnLegendItemClick, PreparedSeries} from './types'; -import {getActiveLegendItems, getAllLegendItems} from './utils'; - -type Args = { - chartWidth: number; - chartHeight: number; - chartMargin: PreparedChart['margin']; - legend: ChartKitWidgetData['legend']; - series: ChartKitWidgetData['series']; - preparedYAxis: PreparedAxis[]; -}; - -export const useSeries = (args: Args) => { - const { - chartWidth, - chartHeight, - chartMargin, - legend, - preparedYAxis, - series: {data: series, options: seriesOptions}, - } = args; - const preparedLegend = React.useMemo( - () => getPreparedLegend({legend, series}), - [legend, series], - ); - const preparedSeries = React.useMemo(() => { - const seriesNames = getSeriesNames(series); - const colorScale = scaleOrdinal(seriesNames, DEFAULT_PALETTE); - const groupedSeries = group(series, (item) => item.type); - - return Array.from(groupedSeries).reduce( - (acc, [seriesType, seriesList]) => { - acc.push( - ...prepareSeries({ - type: seriesType, - series: seriesList, - seriesOptions, - legend: preparedLegend, - colorScale, - }), - ); - return acc; - }, - [], - ); - }, [series, seriesOptions, preparedLegend]); - const preparedSeriesOptions = React.useMemo(() => { - return getPreparedOptions(seriesOptions); - }, [seriesOptions]); - const [activeLegendItems, setActiveLegendItems] = React.useState( - getActiveLegendItems(preparedSeries), - ); - const chartSeries = React.useMemo(() => { - return preparedSeries.map((singleSeries) => { - if (singleSeries.legend.enabled) { - return { - ...singleSeries, - visible: activeLegendItems.includes(singleSeries.name), - }; - } - - return singleSeries; - }); - }, [preparedSeries, activeLegendItems]); - const {legendConfig, legendItems} = React.useMemo(() => { - return getLegendComponents({ - chartHeight, - chartMargin, - chartWidth, - series: chartSeries, - preparedLegend, - preparedYAxis, - }); - }, [chartWidth, chartHeight, chartMargin, chartSeries, preparedLegend, preparedYAxis]); - - const handleLegendItemClick: OnLegendItemClick = React.useCallback( - ({name, metaKey}) => { - const allItems = getAllLegendItems(preparedSeries); - const onlyItemSelected = - activeLegendItems.length === 1 && activeLegendItems.includes(name); - let nextActiveLegendItems: string[]; - - if (metaKey && activeLegendItems.includes(name)) { - nextActiveLegendItems = activeLegendItems.filter((item) => item !== name); - } else if (metaKey && !activeLegendItems.includes(name)) { - nextActiveLegendItems = activeLegendItems.concat(name); - } else if (onlyItemSelected && allItems.length === 1) { - nextActiveLegendItems = []; - } else if (onlyItemSelected) { - nextActiveLegendItems = allItems; - } else { - nextActiveLegendItems = [name]; - } - - setActiveLegendItems(nextActiveLegendItems); - }, - [preparedSeries, activeLegendItems], - ); - - // FIXME: remove effect. It initiates extra rerender - React.useEffect(() => { - setActiveLegendItems(getActiveLegendItems(preparedSeries)); - }, [preparedSeries]); - - return { - legendItems, - legendConfig, - preparedLegend, - preparedSeries: chartSeries, - preparedSeriesOptions, - handleLegendItemClick, - }; -}; diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-area.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-area.ts deleted file mode 100644 index f74ea92f..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-area.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; -import merge from 'lodash/merge'; - -import {AreaSeries, ChartKitWidgetSeriesOptions} from '../../../../../types'; -import {PointMarkerOptions} from '../../../../../types/widget-data/marker'; -import {getRandomCKId} from '../../../../../utils'; - -import { - DEFAULT_DATALABELS_PADDING, - DEFAULT_DATALABELS_STYLE, - DEFAULT_HALO_OPTIONS, - DEFAULT_POINT_MARKER_OPTIONS, -} from './constants'; -import {PreparedAreaSeries, PreparedLegend} from './types'; -import {getSeriesStackId, prepareLegendSymbol} from './utils'; - -export const DEFAULT_LINE_WIDTH = 1; - -export const DEFAULT_MARKER = { - ...DEFAULT_POINT_MARKER_OPTIONS, - enabled: false, -}; - -type PrepareAreaSeriesArgs = { - colorScale: ScaleOrdinal; - series: AreaSeries[]; - seriesOptions?: ChartKitWidgetSeriesOptions; - legend: PreparedLegend; -}; - -function prepareMarker(series: AreaSeries, seriesOptions?: ChartKitWidgetSeriesOptions) { - const seriesHoverState = get(seriesOptions, 'area.states.hover'); - const markerNormalState: Required = Object.assign( - {}, - DEFAULT_MARKER, - seriesOptions?.area?.marker, - series.marker, - ); - const hoveredMarkerDefaultOptions = { - enabled: true, - radius: markerNormalState.radius, - borderWidth: 1, - borderColor: '#ffffff', - halo: DEFAULT_HALO_OPTIONS, - }; - - return { - states: { - normal: markerNormalState, - hover: merge(hoveredMarkerDefaultOptions, seriesHoverState?.marker), - }, - }; -} - -export function prepareArea(args: PrepareAreaSeriesArgs) { - const {colorScale, series: seriesList, seriesOptions, legend} = args; - const defaultAreaWidth = get(seriesOptions, 'area.lineWidth', DEFAULT_LINE_WIDTH); - const defaultOpacity = get(seriesOptions, 'area.opacity', 0.75); - - return seriesList.map((series) => { - const id = getRandomCKId(); - const name = series.name || ''; - const color = series.color || colorScale(name); - - const prepared: PreparedAreaSeries = { - type: series.type, - color, - opacity: get(series, 'opacity', defaultOpacity), - lineWidth: get(series, 'lineWidth', defaultAreaWidth), - name, - id, - visible: get(series, 'visible', true), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(series), - }, - data: series.data, - stacking: series.stacking, - stackId: getSeriesStackId(series), - dataLabels: { - enabled: series.dataLabels?.enabled || false, - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style), - padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - allowOverlap: get(series, 'dataLabels.allowOverlap', false), - html: get(series, 'dataLabels.html', false), - }, - marker: prepareMarker(series, seriesOptions), - cursor: get(series, 'cursor', null), - yAxis: get(series, 'yAxis', 0), - }; - - return prepared; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.ts deleted file mode 100644 index 61d2ee9e..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; - -import type {BarXSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; - -import {DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE} from './constants'; -import type {PreparedBarXSeries, PreparedLegend, PreparedSeries} from './types'; -import {getSeriesStackId, prepareLegendSymbol} from './utils'; - -type PrepareBarXSeriesArgs = { - colorScale: ScaleOrdinal; - series: BarXSeries[]; - legend: PreparedLegend; -}; - -export function prepareBarXSeries(args: PrepareBarXSeriesArgs): PreparedSeries[] { - const {colorScale, series: seriesList, legend} = args; - - return seriesList.map((series) => { - const name = series.name || ''; - const color = series.color || colorScale(name); - - return { - type: series.type, - color, - name, - id: getRandomCKId(), - visible: get(series, 'visible', true), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(series), - }, - data: series.data, - stacking: series.stacking, - stackId: getSeriesStackId(series), - dataLabels: { - enabled: series.dataLabels?.enabled || false, - inside: - typeof series.dataLabels?.inside === 'boolean' - ? series.dataLabels?.inside - : false, - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style), - allowOverlap: series.dataLabels?.allowOverlap || false, - padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - html: get(series, 'dataLabels.html', false), - }, - cursor: get(series, 'cursor', null), - yAxis: get(series, 'yAxis', 0), - }; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.ts deleted file mode 100644 index e0c70ac0..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; - -import type {BarYSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; -import {getLabelsSize} from '../../utils'; - -import {DEFAULT_DATALABELS_STYLE} from './constants'; -import type {PreparedBarYSeries, PreparedLegend, PreparedSeries} from './types'; -import {getSeriesStackId, prepareLegendSymbol} from './utils'; - -type PrepareBarYSeriesArgs = { - colorScale: ScaleOrdinal; - series: BarYSeries[]; - legend: PreparedLegend; -}; - -function prepareDataLabels(series: BarYSeries) { - const enabled = get(series, 'dataLabels.enabled', false); - const style = Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style); - const html = get(series, 'dataLabels.html', false); - const labels = enabled ? series.data.map((d) => String(d.label || d.x)) : []; - const {maxHeight = 0, maxWidth = 0} = getLabelsSize({ - labels, - style, - html, - }); - const inside = series.stacking === 'percent' ? true : get(series, 'dataLabels.inside', false); - - return { - enabled, - inside, - style, - maxHeight, - maxWidth, - html, - }; -} - -export function prepareBarYSeries(args: PrepareBarYSeriesArgs): PreparedSeries[] { - const {colorScale, series: seriesList, legend} = args; - - return seriesList.map((series) => { - const name = series.name || ''; - const color = series.color || colorScale(name); - - return { - type: series.type, - color, - name, - id: getRandomCKId(), - visible: get(series, 'visible', true), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(series), - }, - data: series.data, - stacking: series.stacking, - stackId: getSeriesStackId(series), - dataLabels: prepareDataLabels(series), - cursor: get(series, 'cursor', null), - }; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-legend.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-legend.ts deleted file mode 100644 index 3effa534..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-legend.ts +++ /dev/null @@ -1,200 +0,0 @@ -import {select} from 'd3'; -import clone from 'lodash/clone'; -import get from 'lodash/get'; -import merge from 'lodash/merge'; - -import type {BaseTextStyle, ChartKitWidgetData} from '../../../../../types'; -import {CONTINUOUS_LEGEND_SIZE, legendDefaults} from '../../constants'; -import { - getDefaultColorStops, - getDomainForContinuousColorScale, - getHorisontalSvgTextHeight, - getLabelsSize, -} from '../../utils'; -import {getBoundsWidth} from '../useChartDimensions'; -import {getYAxisWidth} from '../useChartDimensions/utils'; -import type {PreparedAxis, PreparedChart} from '../useChartOptions/types'; - -import type {LegendConfig, LegendItem, PreparedLegend, PreparedSeries} from './types'; - -type LegendItemWithoutTextWidth = Omit; - -export const getPreparedLegend = (args: { - legend: ChartKitWidgetData['legend']; - series: ChartKitWidgetData['series']['data']; -}): PreparedLegend => { - const {legend, series} = args; - const enabled = Boolean( - typeof legend?.enabled === 'boolean' ? legend?.enabled : series.length > 1, - ); - const defaultItemStyle = clone(legendDefaults.itemStyle); - const itemStyle = get(legend, 'itemStyle'); - const computedItemStyle = merge(defaultItemStyle, itemStyle); - const lineHeight = getHorisontalSvgTextHeight({text: 'Tmp', style: computedItemStyle}); - - const legendType = get(legend, 'type', 'discrete'); - const isTitleEnabled = Boolean(legend?.title?.text); - const titleMargin = isTitleEnabled ? get(legend, 'title.margin', 4) : 0; - const titleStyle: BaseTextStyle = { - fontSize: '12px', - fontWeight: 'bold', - ...get(legend, 'title.style'), - }; - const titleText = isTitleEnabled ? get(legend, 'title.text', '') : ''; - const titleHeight = isTitleEnabled - ? getLabelsSize({labels: [titleText], style: titleStyle}).maxHeight - : 0; - - const ticks = { - labelsMargin: 4, - labelsLineHeight: 12, - }; - - const colorScale: PreparedLegend['colorScale'] = { - colors: [], - domain: [], - stops: [], - }; - - let height = 0; - if (enabled) { - height += titleHeight + titleMargin; - if (legendType === 'continuous') { - height += CONTINUOUS_LEGEND_SIZE.height; - height += ticks.labelsLineHeight + ticks.labelsMargin; - - colorScale.colors = legend?.colorScale?.colors ?? []; - colorScale.stops = - legend?.colorScale?.stops ?? getDefaultColorStops(colorScale.colors.length); - colorScale.domain = - legend?.colorScale?.domain ?? getDomainForContinuousColorScale({series}); - } else { - height += lineHeight; - } - } - - const legendWidth = get(legend, 'width', CONTINUOUS_LEGEND_SIZE.width); - - return { - align: get(legend, 'align', legendDefaults.align), - enabled, - height, - itemDistance: get(legend, 'itemDistance', legendDefaults.itemDistance), - itemStyle: computedItemStyle, - lineHeight, - margin: get(legend, 'margin', legendDefaults.margin), - type: legendType, - title: { - enable: isTitleEnabled, - text: titleText, - margin: titleMargin, - style: titleStyle, - height: titleHeight, - }, - width: legendWidth, - ticks, - colorScale, - }; -}; - -const getFlattenLegendItems = (series: PreparedSeries[]) => { - return series.reduce((acc, s) => { - const legendEnabled = get(s, 'legend.enabled', true); - - if (legendEnabled) { - acc.push({ - ...s, - symbol: s.legend.symbol, - }); - } - - return acc; - }, []); -}; - -const getGroupedLegendItems = (args: { - maxLegendWidth: number; - items: LegendItemWithoutTextWidth[]; - preparedLegend: PreparedLegend; -}) => { - const {maxLegendWidth, items, preparedLegend} = args; - const result: LegendItem[][] = [[]]; - let textWidthsInLine: number[] = [0]; - let lineIndex = 0; - - items.forEach((item) => { - select(document.body) - .append('text') - .text(item.name) - .style('font-size', preparedLegend.itemStyle.fontSize) - .each(function () { - const resultItem = clone(item) as LegendItem; - const textWidth = this.getBoundingClientRect().width; - resultItem.textWidth = textWidth; - textWidthsInLine.push(textWidth); - const textsWidth = textWidthsInLine.reduce((acc, width) => acc + width, 0); - result[lineIndex].push(resultItem); - const symbolsWidth = result[lineIndex].reduce((acc, {symbol}) => { - return acc + symbol.width + symbol.padding; - }, 0); - const distancesWidth = (result[lineIndex].length - 1) * preparedLegend.itemDistance; - const isOverfilled = maxLegendWidth < textsWidth + symbolsWidth + distancesWidth; - - if (isOverfilled) { - result[lineIndex].pop(); - lineIndex += 1; - textWidthsInLine = [textWidth]; - const nextLineIndex = lineIndex; - result[nextLineIndex] = []; - result[nextLineIndex].push(resultItem); - } - }) - .remove(); - }); - - return result; -}; - -export const getLegendComponents = (args: { - chartWidth: number; - chartHeight: number; - chartMargin: PreparedChart['margin']; - series: PreparedSeries[]; - preparedLegend: PreparedLegend; - preparedYAxis: PreparedAxis[]; -}) => { - const {chartWidth, chartHeight, chartMargin, series, preparedLegend, preparedYAxis} = args; - const maxLegendWidth = getBoundsWidth({chartWidth, chartMargin, preparedYAxis}); - const maxLegendHeight = - (chartHeight - chartMargin.top - chartMargin.bottom - preparedLegend.margin) / 2; - const flattenLegendItems = getFlattenLegendItems(series); - const items = getGroupedLegendItems({ - maxLegendWidth, - items: flattenLegendItems, - preparedLegend, - }); - - let pagination: LegendConfig['pagination'] | undefined; - - if (preparedLegend.type === 'discrete') { - let legendHeight = preparedLegend.lineHeight * items.length; - - if (maxLegendHeight < legendHeight) { - // extra line for paginator - const limit = Math.floor(maxLegendHeight / preparedLegend.lineHeight) - 1; - const maxPage = Math.ceil(items.length / limit); - pagination = {limit, maxPage}; - legendHeight = maxLegendHeight; - } - - preparedLegend.height = legendHeight; - } - - const top = chartHeight - chartMargin.bottom - preparedLegend.height; - const offset: LegendConfig['offset'] = { - left: chartMargin.left + getYAxisWidth(preparedYAxis[0]), - top, - }; - - return {legendConfig: {offset, pagination}, legendItems: items}; -}; diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-line.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-line.ts deleted file mode 100644 index f52ce885..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-line.ts +++ /dev/null @@ -1,130 +0,0 @@ -import {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; -import merge from 'lodash/merge'; - -import {DashStyle, LineCap} from '../../../../../constants'; -import { - ChartKitWidgetSeries, - ChartKitWidgetSeriesOptions, - LineSeries, - RectLegendSymbolOptions, -} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; - -import { - DEFAULT_DATALABELS_PADDING, - DEFAULT_DATALABELS_STYLE, - DEFAULT_HALO_OPTIONS, - DEFAULT_LEGEND_SYMBOL_PADDING, - DEFAULT_POINT_MARKER_OPTIONS, -} from './constants'; -import {PreparedLegend, PreparedLegendSymbol, PreparedLineSeries} from './types'; - -export const DEFAULT_LEGEND_SYMBOL_SIZE = 16; -export const DEFAULT_LINE_WIDTH = 1; -export const DEFAULT_DASH_STYLE = DashStyle.Solid; - -export const DEFAULT_MARKER = { - ...DEFAULT_POINT_MARKER_OPTIONS, - enabled: false, -}; - -type PrepareLineSeriesArgs = { - colorScale: ScaleOrdinal; - series: LineSeries[]; - seriesOptions?: ChartKitWidgetSeriesOptions; - legend: PreparedLegend; -}; - -function prepareLinecap( - dashStyle: DashStyle, - series: LineSeries, - seriesOptions?: ChartKitWidgetSeriesOptions, -) { - const defaultLineCap = dashStyle === DashStyle.Solid ? LineCap.Round : LineCap.None; - const lineCapFromSeriesOptions = get(seriesOptions, 'line.linecap', defaultLineCap); - - return get(series, 'linecap', lineCapFromSeriesOptions); -} - -function prepareLineLegendSymbol( - series: ChartKitWidgetSeries, - seriesOptions?: ChartKitWidgetSeriesOptions, -): PreparedLegendSymbol { - const symbolOptions: RectLegendSymbolOptions = series.legend?.symbol || {}; - const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH); - - return { - shape: 'path', - width: symbolOptions?.width || DEFAULT_LEGEND_SYMBOL_SIZE, - padding: symbolOptions?.padding || DEFAULT_LEGEND_SYMBOL_PADDING, - strokeWidth: get(series, 'lineWidth', defaultLineWidth), - }; -} - -function prepareMarker(series: LineSeries, seriesOptions?: ChartKitWidgetSeriesOptions) { - const seriesHoverState = get(seriesOptions, 'line.states.hover'); - const markerNormalState = Object.assign( - {}, - DEFAULT_MARKER, - seriesOptions?.line?.marker, - series.marker, - ); - const hoveredMarkerDefaultOptions = { - enabled: true, - radius: markerNormalState.radius, - borderWidth: 1, - borderColor: '#ffffff', - halo: DEFAULT_HALO_OPTIONS, - }; - - return { - states: { - normal: markerNormalState, - hover: merge(hoveredMarkerDefaultOptions, seriesHoverState?.marker), - }, - }; -} - -export function prepareLineSeries(args: PrepareLineSeriesArgs) { - const {colorScale, series: seriesList, seriesOptions, legend} = args; - - const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH); - const defaultDashStyle = get(seriesOptions, 'line.dashStyle', DEFAULT_DASH_STYLE); - - return seriesList.map((series) => { - const id = getRandomCKId(); - const name = series.name || ''; - const color = series.color || colorScale(name); - const dashStyle = get(series, 'dashStyle', defaultDashStyle); - - const prepared: PreparedLineSeries = { - type: series.type, - color, - lineWidth: get(series, 'lineWidth', defaultLineWidth), - name, - id, - visible: get(series, 'visible', true), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLineLegendSymbol(series, seriesOptions), - }, - data: series.data, - dataLabels: { - enabled: series.dataLabels?.enabled || false, - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style), - padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - allowOverlap: get(series, 'dataLabels.allowOverlap', false), - html: get(series, 'dataLabels.html', false), - }, - marker: prepareMarker(series, seriesOptions), - dashStyle: dashStyle as DashStyle, - linecap: prepareLinecap(dashStyle as DashStyle, series, seriesOptions) as LineCap, - opacity: get(series, 'opacity', null), - cursor: get(series, 'cursor', null), - yAxis: get(series, 'yAxis', 0), - }; - - return prepared; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-options.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-options.ts deleted file mode 100644 index a579bb59..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-options.ts +++ /dev/null @@ -1,12 +0,0 @@ -import merge from 'lodash/merge'; - -import type {ChartKitWidgetSeriesOptions} from '../../../../../types/widget-data'; -import {seriesOptionsDefaults} from '../../constants'; - -import type {PreparedSeriesOptions} from './types'; - -export const getPreparedOptions = ( - options?: ChartKitWidgetSeriesOptions, -): PreparedSeriesOptions => { - return merge({}, seriesOptionsDefaults, options); -}; diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-pie.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-pie.ts deleted file mode 100644 index 900f5342..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-pie.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {scaleOrdinal} from 'd3'; -import get from 'lodash/get'; - -import {ChartKitWidgetSeriesOptions, PieSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; -import {DEFAULT_PALETTE} from '../../constants'; - -import {DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE} from './constants'; -import {PreparedLegend, PreparedPieSeries, PreparedSeries} from './types'; -import {prepareLegendSymbol} from './utils'; - -type PreparePieSeriesArgs = { - series: PieSeries; - seriesOptions?: ChartKitWidgetSeriesOptions; - legend: PreparedLegend; -}; - -export function preparePieSeries(args: PreparePieSeriesArgs) { - const {series, seriesOptions, legend} = args; - const dataNames = series.data.map((d) => d.name); - const colorScale = scaleOrdinal(dataNames, DEFAULT_PALETTE); - const stackId = getRandomCKId(); - const seriesHoverState = get(seriesOptions, 'pie.states.hover'); - - const preparedSeries: PreparedSeries[] = series.data.map((dataItem, i) => { - const result: PreparedPieSeries = { - type: 'pie', - data: dataItem, - dataLabels: { - enabled: get(series, 'dataLabels.enabled', true), - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style), - padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - allowOverlap: get(series, 'dataLabels.allowOverlap', false), - connectorPadding: get(series, 'dataLabels.connectorPadding', 5), - connectorShape: get(series, 'dataLabels.connectorShape', 'polyline'), - distance: get(series, 'dataLabels.distance', 25), - connectorCurve: get(series, 'dataLabels.connectorCurve', 'basic'), - html: get(series, 'dataLabels.html', false), - }, - label: dataItem.label, - value: dataItem.value, - visible: typeof dataItem.visible === 'boolean' ? dataItem.visible : true, - name: dataItem.name, - id: `Series ${i}`, - color: dataItem.color || colorScale(dataItem.name), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(series), - }, - center: series.center || ['50%', '50%'], - borderColor: series.borderColor || '', - borderRadius: series.borderRadius ?? 0, - borderWidth: series.borderWidth ?? 1, - radius: series.radius || '100%', - innerRadius: series.innerRadius || 0, - stackId, - states: { - hover: { - halo: { - enabled: get(seriesHoverState, 'halo.enabled', true), - opacity: get(seriesHoverState, 'halo.opacity', 0.25), - size: get(seriesHoverState, 'halo.size', 10), - }, - }, - }, - renderCustomShape: series.renderCustomShape, - opacity: get(dataItem, 'opacity', null), - cursor: get(series, 'cursor', null), - }; - - return result; - }); - - return preparedSeries; -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-scatter.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-scatter.ts deleted file mode 100644 index 47a692cf..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-scatter.ts +++ /dev/null @@ -1,75 +0,0 @@ -import {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; -import merge from 'lodash/merge'; - -import type {ChartKitWidgetSeriesOptions, ScatterSeries} from '../../../../../types'; -import {PointMarkerOptions} from '../../../../../types/widget-data/marker'; -import {getRandomCKId} from '../../../../../utils'; -import {getSymbolType} from '../../utils'; - -import {DEFAULT_HALO_OPTIONS, DEFAULT_POINT_MARKER_OPTIONS} from './constants'; -import type {PreparedLegend, PreparedScatterSeries} from './types'; -import {prepareLegendSymbol} from './utils'; - -function prepareMarker( - series: ScatterSeries, - seriesOptions: ChartKitWidgetSeriesOptions | undefined, - index: number, -) { - const seriesHoverState = get(seriesOptions, 'scatter.states.hover'); - const markerNormalState: Required = { - ...DEFAULT_POINT_MARKER_OPTIONS, - enabled: true, - symbol: (series as ScatterSeries).symbolType || getSymbolType(index), - }; - - const hoveredMarkerDefaultOptions = { - enabled: true, - radius: markerNormalState.radius, - borderWidth: 1, - borderColor: '#ffffff', - halo: DEFAULT_HALO_OPTIONS, - }; - - return { - states: { - normal: markerNormalState, - hover: merge(hoveredMarkerDefaultOptions, seriesHoverState?.marker), - }, - }; -} - -interface PrepareScatterSeriesArgs { - colorScale: ScaleOrdinal; - series: ScatterSeries[]; - legend: PreparedLegend; - seriesOptions?: ChartKitWidgetSeriesOptions; -} - -export function prepareScatterSeries(args: PrepareScatterSeriesArgs): PreparedScatterSeries[] { - const {colorScale, series, seriesOptions, legend} = args; - - return series.map((s, index) => { - const id = getRandomCKId(); - const name = 'name' in s && s.name ? s.name : ''; - const symbolType = (s as ScatterSeries).symbolType || getSymbolType(index); - - const prepared: PreparedScatterSeries = { - id, - type: s.type, - name, - color: get(s, 'color', colorScale(name)), - visible: get(s, 'visible', true), - legend: { - enabled: get(s, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(s, symbolType), - }, - data: s.data, - marker: prepareMarker(s, seriesOptions, index), - cursor: get(s, 'cursor', null), - yAxis: get(s, 'yAxis', 0), - }; - - return prepared; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-treemap.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-treemap.ts deleted file mode 100644 index 460be2a7..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-treemap.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; - -import {LayoutAlgorithm} from '../../../../../constants'; -import type {ChartKitWidgetSeriesOptions, TreemapSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; - -import {DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE} from './constants'; -import type {PreparedLegend, PreparedTreemapSeries} from './types'; -import {prepareLegendSymbol} from './utils'; - -type PrepareTreemapSeriesArgs = { - colorScale: ScaleOrdinal; - legend: PreparedLegend; - series: TreemapSeries[]; - seriesOptions?: ChartKitWidgetSeriesOptions; -}; - -export function prepareTreemap(args: PrepareTreemapSeriesArgs) { - const {colorScale, legend, series} = args; - - return series.map((s) => { - const id = getRandomCKId(); - const name = s.name || ''; - const color = s.color || colorScale(name); - - const preparedSeries: PreparedTreemapSeries = { - color, - data: s.data, - dataLabels: { - enabled: get(s, 'dataLabels.enabled', true), - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, s.dataLabels?.style), - padding: get(s, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - allowOverlap: get(s, 'dataLabels.allowOverlap', false), - html: get(s, 'dataLabels.html', false), - align: get(s, 'dataLabels.align', 'left'), - }, - id, - type: s.type, - name, - visible: get(s, 'visible', true), - legend: { - enabled: get(s, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(s), - }, - levels: s.levels, - layoutAlgorithm: get(s, 'layoutAlgorithm', LayoutAlgorithm.Binary), - cursor: get(s, 'cursor', null), - }; - - return preparedSeries; - }); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepare-waterfall.ts b/src/plugins/d3/renderer/hooks/useSeries/prepare-waterfall.ts deleted file mode 100644 index 467085fb..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepare-waterfall.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type {ScaleOrdinal} from 'd3'; -import get from 'lodash/get'; - -import type {WaterfallSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; -import {DEFAULT_PALETTE} from '../../constants'; - -import {DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE} from './constants'; -import type {PreparedLegend, PreparedSeries, PreparedWaterfallSeries} from './types'; -import {prepareLegendSymbol} from './utils'; - -type PrepareWaterfallSeriesArgs = { - colorScale: ScaleOrdinal; - series: WaterfallSeries[]; - legend: PreparedLegend; -}; - -export function prepareWaterfallSeries(args: PrepareWaterfallSeriesArgs): PreparedSeries[] { - const {colorScale, series: seriesList, legend} = args; - const [, negativeColor, positiveColor] = DEFAULT_PALETTE; - - return seriesList.map((series) => { - const name = series.name || ''; - const color = series.color || colorScale(name); - - const prepared: PreparedWaterfallSeries = { - type: series.type, - color, - positiveColor: positiveColor, - negativeColor: negativeColor, - name, - id: getRandomCKId(), - visible: get(series, 'visible', true), - legend: { - enabled: get(series, 'legend.enabled', legend.enabled), - symbol: prepareLegendSymbol(series), - }, - data: series.data, - dataLabels: { - enabled: series.dataLabels?.enabled || false, - style: Object.assign({}, DEFAULT_DATALABELS_STYLE, series.dataLabels?.style), - allowOverlap: series.dataLabels?.allowOverlap || false, - padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING), - html: get(series, 'dataLabels.html', false), - }, - cursor: get(series, 'cursor', null), - }; - return prepared; - }, []); -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/prepareSeries.ts b/src/plugins/d3/renderer/hooks/useSeries/prepareSeries.ts deleted file mode 100644 index bcd0999e..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/prepareSeries.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type {ScaleOrdinal} from 'd3'; - -import {ChartKitError} from '../../../../../libs'; -import type { - AreaSeries, - BarXSeries, - BarYSeries, - ChartKitWidgetSeries, - ChartKitWidgetSeriesOptions, - LineSeries, - PieSeries, - ScatterSeries, - TreemapSeries, - WaterfallSeries, -} from '../../../../../types'; - -import {prepareArea} from './prepare-area'; -import {prepareBarXSeries} from './prepare-bar-x'; -import {prepareBarYSeries} from './prepare-bar-y'; -import {prepareLineSeries} from './prepare-line'; -import {preparePieSeries} from './prepare-pie'; -import {prepareScatterSeries} from './prepare-scatter'; -import {prepareTreemap} from './prepare-treemap'; -import {prepareWaterfallSeries} from './prepare-waterfall'; -import type {PreparedLegend, PreparedSeries} from './types'; - -export function prepareSeries(args: { - type: ChartKitWidgetSeries['type']; - series: ChartKitWidgetSeries[]; - seriesOptions?: ChartKitWidgetSeriesOptions; - legend: PreparedLegend; - colorScale: ScaleOrdinal; -}): PreparedSeries[] { - const {type, series, seriesOptions, legend, colorScale} = args; - - switch (type) { - case 'pie': { - return series.reduce((acc, singleSeries) => { - acc.push( - ...preparePieSeries({series: singleSeries as PieSeries, seriesOptions, legend}), - ); - return acc; - }, []); - } - case 'bar-x': { - return prepareBarXSeries({series: series as BarXSeries[], legend, colorScale}); - } - case 'bar-y': { - return prepareBarYSeries({series: series as BarYSeries[], legend, colorScale}); - } - case 'scatter': { - return prepareScatterSeries({series: series as ScatterSeries[], legend, colorScale}); - } - case 'line': { - return prepareLineSeries({ - series: series as LineSeries[], - seriesOptions, - legend, - colorScale, - }); - } - case 'area': { - return prepareArea({ - series: series as AreaSeries[], - seriesOptions, - legend, - colorScale, - }); - } - case 'treemap': { - return prepareTreemap({ - series: series as TreemapSeries[], - seriesOptions, - legend, - colorScale, - }); - } - case 'waterfall': { - return prepareWaterfallSeries({ - series: series as WaterfallSeries[], - legend, - colorScale, - }); - } - default: { - throw new ChartKitError({ - message: `Series type "${type}" does not support data preparation for series that do not support the presence of axes`, - }); - } - } -} diff --git a/src/plugins/d3/renderer/hooks/useSeries/types.ts b/src/plugins/d3/renderer/hooks/useSeries/types.ts deleted file mode 100644 index de997dee..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/types.ts +++ /dev/null @@ -1,304 +0,0 @@ -import {DashStyle, LayoutAlgorithm, LineCap, SymbolType} from '../../../../../constants'; -import type { - AreaSeries, - AreaSeriesData, - BarXSeries, - BarXSeriesData, - BarYSeries, - BarYSeriesData, - BaseTextStyle, - ChartKitWidgetLegend, - ConnectorCurve, - ConnectorShape, - LineSeries, - LineSeriesData, - PathLegendSymbolOptions, - PieSeries, - PieSeriesData, - RectLegendSymbolOptions, - ScatterSeries, - ScatterSeriesData, - SymbolLegendSymbolOptions, - TreemapSeries, - TreemapSeriesData, - WaterfallSeries, - WaterfallSeriesData, -} from '../../../../../types'; -import type {SeriesOptionsDefaults} from '../../constants'; - -export type RectLegendSymbol = { - shape: 'rect'; -} & Required; - -export type PathLegendSymbol = { - shape: 'path'; - strokeWidth: number; -} & Required; - -export type SymbolLegendSymbol = { - shape: 'symbol'; - symbolType: `${SymbolType}`; -} & Required; - -export type PreparedLegendSymbol = RectLegendSymbol | PathLegendSymbol | SymbolLegendSymbol; - -export type PreparedLegend = Required> & { - height: number; - lineHeight: number; - title: { - enable: boolean; - text: string; - margin: number; - style: BaseTextStyle; - height: number; - }; - ticks: { - labelsMargin: number; - labelsLineHeight: number; - }; - colorScale: { - colors: string[]; - domain: number[]; - stops: number[]; - }; -}; - -export type OnLegendItemClick = (data: {name: string; metaKey: boolean}) => void; - -export type LegendItem = { - color: string; - name: string; - symbol: PreparedLegendSymbol; - textWidth: number; - visible?: boolean; - dashStyle?: DashStyle; -}; - -export type LegendConfig = { - offset: { - left: number; - top: number; - }; - pagination?: { - limit: number; - maxPage: number; - }; -}; - -export type PreparedHaloOptions = { - enabled: boolean; - opacity: number; - size: number; -}; - -type BasePreparedSeries = { - color: string; - name: string; - id: string; - visible: boolean; - legend: { - enabled: boolean; - symbol: PreparedLegendSymbol; - }; - cursor: string | null; -}; - -export type PreparedScatterSeries = { - type: ScatterSeries['type']; - data: ScatterSeriesData[]; - marker: { - states: { - normal: { - symbol: `${SymbolType}`; - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - }; - hover: { - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - halo: PreparedHaloOptions; - }; - }; - }; - yAxis: number; -} & BasePreparedSeries; - -export type PreparedBarXSeries = { - type: BarXSeries['type']; - data: BarXSeriesData[]; - stackId: string; - stacking: BarXSeries['stacking']; - dataLabels: { - enabled: boolean; - inside: boolean; - style: BaseTextStyle; - allowOverlap: boolean; - padding: number; - html: boolean; - }; - yAxis: number; -} & BasePreparedSeries; - -export type PreparedBarYSeries = { - type: BarYSeries['type']; - data: BarYSeriesData[]; - stackId: string; - stacking: BarYSeries['stacking']; - dataLabels: { - enabled: boolean; - inside: boolean; - style: BaseTextStyle; - maxHeight: number; - maxWidth: number; - html: boolean; - }; -} & BasePreparedSeries; - -export type PreparedPieSeries = { - type: PieSeries['type']; - data: PieSeriesData; - value: PieSeriesData['value']; - borderColor: string; - borderWidth: number; - borderRadius: number; - center?: [string | number | null, string | number | null]; - radius?: string | number; - innerRadius?: string | number; - stackId: string; - label?: PieSeriesData['label']; - dataLabels: { - enabled: boolean; - padding: number; - style: BaseTextStyle; - allowOverlap: boolean; - connectorPadding: number; - connectorShape: ConnectorShape; - distance: number; - connectorCurve: ConnectorCurve; - html: boolean; - }; - states: { - hover: { - halo: PreparedHaloOptions; - }; - }; - renderCustomShape?: PieSeries['renderCustomShape']; - opacity: number | null; -} & BasePreparedSeries; - -export type PreparedLineSeries = { - type: LineSeries['type']; - data: LineSeriesData[]; - lineWidth: number; - dataLabels: { - enabled: boolean; - style: BaseTextStyle; - padding: number; - allowOverlap: boolean; - html: boolean; - }; - marker: { - states: { - normal: { - symbol: `${SymbolType}`; - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - }; - hover: { - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - halo: PreparedHaloOptions; - }; - }; - }; - dashStyle: DashStyle; - linecap: LineCap; - opacity: number | null; - yAxis: number; -} & BasePreparedSeries; - -export type PreparedAreaSeries = { - type: AreaSeries['type']; - data: AreaSeriesData[]; - stacking: AreaSeries['stacking']; - stackId: string; - lineWidth: number; - opacity: number; - dataLabels: { - enabled: boolean; - style: BaseTextStyle; - padding: number; - allowOverlap: boolean; - html: boolean; - }; - marker: { - states: { - normal: { - symbol: `${SymbolType}`; - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - }; - hover: { - enabled: boolean; - radius: number; - borderWidth: number; - borderColor: string; - halo: PreparedHaloOptions; - }; - }; - }; - yAxis: number; -} & BasePreparedSeries; - -export type PreparedTreemapSeries = { - type: TreemapSeries['type']; - data: TreemapSeriesData[]; - dataLabels: { - enabled: boolean; - style: BaseTextStyle; - padding: number; - allowOverlap: boolean; - html: boolean; - align: Required['dataLabels']>['align']; - }; - layoutAlgorithm: `${LayoutAlgorithm}`; -} & BasePreparedSeries & - Omit; - -export type PreparedWaterfallSeries = { - type: WaterfallSeries['type']; - data: WaterfallSeriesData[]; - dataLabels: { - enabled: boolean; - style: BaseTextStyle; - allowOverlap: boolean; - padding: number; - html: boolean; - }; - positiveColor: string; - negativeColor: string; -} & BasePreparedSeries; - -export type PreparedSeries = - | PreparedScatterSeries - | PreparedBarXSeries - | PreparedBarYSeries - | PreparedPieSeries - | PreparedLineSeries - | PreparedAreaSeries - | PreparedTreemapSeries - | PreparedWaterfallSeries; - -export type PreparedSeriesOptions = SeriesOptionsDefaults; - -export type StackedSeries = BarXSeries | AreaSeries | BarYSeries; diff --git a/src/plugins/d3/renderer/hooks/useSeries/utils.ts b/src/plugins/d3/renderer/hooks/useSeries/utils.ts deleted file mode 100644 index 948a25e0..00000000 --- a/src/plugins/d3/renderer/hooks/useSeries/utils.ts +++ /dev/null @@ -1,48 +0,0 @@ -import memoize from 'lodash/memoize'; - -import {SymbolType} from '../../../../../constants'; -import {ChartKitWidgetSeries} from '../../../../../types'; -import {getRandomCKId} from '../../../../../utils'; - -import {DEFAULT_LEGEND_SYMBOL_PADDING, DEFAULT_LEGEND_SYMBOL_SIZE} from './constants'; -import {PreparedLegendSymbol, PreparedSeries, StackedSeries} from './types'; - -export const getActiveLegendItems = (series: PreparedSeries[]) => { - return series.reduce((acc, s) => { - if (s.legend.enabled && s.visible) { - acc.push(s.name); - } - - return acc; - }, []); -}; - -export const getAllLegendItems = (series: PreparedSeries[]) => { - return series.map((s) => s.name); -}; - -export function prepareLegendSymbol( - series: ChartKitWidgetSeries, - symbolType?: `${SymbolType}`, -): PreparedLegendSymbol { - const symbolOptions = series.legend?.symbol || {}; - - return { - shape: 'symbol', - symbolType: symbolType || SymbolType.Circle, - width: symbolOptions?.width || DEFAULT_LEGEND_SYMBOL_SIZE, - padding: symbolOptions?.padding || DEFAULT_LEGEND_SYMBOL_PADDING, - }; -} - -const getCommonStackId = memoize(getRandomCKId); - -export function getSeriesStackId(series: StackedSeries) { - let stackId = series.stackId; - - if (!stackId) { - stackId = series.stacking ? getCommonStackId() : getRandomCKId(); - } - - return stackId; -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/HtmlLayer.tsx b/src/plugins/d3/renderer/hooks/useShapes/HtmlLayer.tsx deleted file mode 100644 index 3560eff8..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/HtmlLayer.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; - -import {Portal} from '@gravity-ui/uikit'; - -import {HtmlItem, ShapeDataWithHtmlItems} from '../../types'; - -type Props = { - htmlLayout: HTMLElement | null; - preparedData: ShapeDataWithHtmlItems | ShapeDataWithHtmlItems[]; -}; - -export const HtmlLayer = (props: Props) => { - const {htmlLayout, preparedData} = props; - - const items = React.useMemo(() => { - if (Array.isArray(preparedData)) { - return preparedData.reduce((result, d) => { - result.push(...d.htmlElements); - return result; - }, []); - } else { - return preparedData.htmlElements; - } - }, [preparedData]); - - if (!htmlLayout) { - return null; - } - - return ( - - {items.map((item, index) => { - return ( -
- ); - })} - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/area/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/area/index.tsx deleted file mode 100644 index a820f758..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/area/index.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import React from 'react'; - -import type {BaseType, Dispatch} from 'd3'; -import {area as areaGenerator, color, line as lineGenerator, select} from 'd3'; -import get from 'lodash/get'; - -import type {TooltipDataChunkArea} from '../../../../../../types'; -import {block} from '../../../../../../utils/cn'; -import type {LabelData} from '../../../types'; -import {filterOverlappingLabels} from '../../../utils'; -import type {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; -import { - getMarkerHaloVisibility, - getMarkerVisibility, - renderMarker, - selectMarkerHalo, - selectMarkerSymbol, - setMarker, -} from '../marker'; -import {setActiveState} from '../utils'; - -import type {MarkerData, PointData, PreparedAreaData} from './types'; - -const b = block('d3-area'); - -type Args = { - dispatcher: Dispatch; - preparedData: PreparedAreaData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const AreaSeriesShapes = (args: Args) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - const hoverOptions = get(seriesOptions, 'area.states.hover'); - const inactiveOptions = get(seriesOptions, 'area.states.inactive'); - - const line = lineGenerator() - .x((d) => d.x) - .y((d) => d.y); - - svgElement.selectAll('*').remove(); - - const shapeSelection = svgElement - .selectAll('shape') - .data(preparedData) - .join('g') - .attr('class', b('series')) - .attr('cursor', (d) => d.series.cursor); - - shapeSelection - .append('path') - .attr('class', b('line')) - .attr('d', (d) => line(d.points)) - .attr('fill', 'none') - .attr('stroke', (d) => d.color) - .attr('stroke-width', (d) => d.width) - .attr('stroke-linejoin', 'round') - .attr('stroke-linecap', 'round'); - - const area = areaGenerator() - .x((d) => d.x) - .y0((d) => d.y0) - .y1((d) => d.y); - shapeSelection - .append('path') - .attr('class', b('region')) - .attr('d', (d) => area(d.points)) - .attr('fill', (d) => d.color) - .attr('opacity', (d) => d.opacity); - - let dataLabels = preparedData.reduce((acc, d) => { - return acc.concat(d.labels); - }, [] as LabelData[]); - - if (!preparedData[0]?.series.dataLabels.allowOverlap) { - dataLabels = filterOverlappingLabels(dataLabels); - } - - const labelsSelection = svgElement - .selectAll('text') - .data(dataLabels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null); - - const markers = preparedData.reduce((acc, d) => acc.concat(d.markers), []); - const markerSelection = svgElement - .selectAll('marker') - .data(markers) - .join('g') - .call(renderMarker); - - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - dispatcher.on('hover-shape.area', (data?: TooltipDataChunkArea[]) => { - const selected = data?.filter((d) => d.series.type === 'area') || []; - const selectedDataItems = selected.map((d) => d.data); - const selectedSeriesIds = selected.map((d) => d.series?.id); - - shapeSelection.datum((d, index, list) => { - const elementSelection = select(list[index]); - - const hovered = Boolean(hoverEnabled && selectedSeriesIds.includes(d.id)); - if (d.hovered !== hovered) { - d.hovered = hovered; - - let strokeColor = d.color || ''; - if (d.hovered) { - strokeColor = - color(strokeColor)?.brighter(hoverOptions?.brightness).toString() || - strokeColor; - } - - elementSelection.selectAll(`.${b('line')}`).attr('stroke', strokeColor); - elementSelection.selectAll(`.${b('region')}`).attr('fill', strokeColor); - } - - return setActiveState({ - element: list[index], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.id), - ), - datum: d, - }); - }); - - labelsSelection.datum((d, index, list) => { - return setActiveState({ - element: list[index], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.series.id), - ), - datum: d, - }); - }); - - markerSelection.datum((d, index, list) => { - const elementSelection = select(list[index]); - - const hovered = Boolean(hoverEnabled && selectedDataItems.includes(d.point.data)); - if (d.hovered !== hovered) { - d.hovered = hovered; - elementSelection.attr('visibility', getMarkerVisibility(d)); - selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility); - selectMarkerSymbol(elementSelection).call( - setMarker, - hovered ? 'hover' : 'normal', - ); - } - - if (d.point.series.marker.states.normal.enabled) { - const isActive = Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.point.series.id), - ); - setActiveState({ - element: list[index], - state: inactiveOptions, - active: isActive, - datum: d, - }); - } - return d; - }); - }); - - return () => { - dispatcher.on('hover-shape.area', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/area/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/area/prepare-data.ts deleted file mode 100644 index 9ef8df60..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/area/prepare-data.ts +++ /dev/null @@ -1,203 +0,0 @@ -import {group, sort} from 'd3'; - -import type {AreaSeriesData} from '../../../../../../types'; -import type {HtmlItem, LabelData} from '../../../types'; -import {getDataCategoryValue, getLabelsSize, getLeftPosition} from '../../../utils'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import type {PreparedAreaSeries} from '../../useSeries/types'; -import {getXValue, getYValue} from '../utils'; - -import type {MarkerData, PointData, PreparedAreaData} from './types'; - -function getLabelData(point: PointData, series: PreparedAreaSeries, xMax: number) { - const text = String(point.data.label || point.data.y); - const style = series.dataLabels.style; - const size = getLabelsSize({labels: [text], style, html: series.dataLabels.html}); - - const labelData: LabelData = { - text, - x: point.x, - y: point.y - series.dataLabels.padding, - style, - size: {width: size.maxWidth, height: size.maxHeight}, - textAnchor: 'middle', - series: series, - active: true, - }; - - const left = getLeftPosition(labelData); - if (left < 0) { - labelData.x = labelData.x + Math.abs(left); - } else { - const right = left + labelData.size.width; - if (right > xMax) { - labelData.x = labelData.x - (right - xMax); - } - } - - return labelData; -} - -function getXValues(series: PreparedAreaSeries[], xAxis: PreparedAxis, xScale: ChartScale) { - const categories = xAxis.categories || []; - const xValues = series.reduce>((acc, s) => { - s.data.forEach((d) => { - const key = String( - xAxis.type === 'category' - ? getDataCategoryValue({axisDirection: 'x', categories, data: d}) - : d.x, - ); - if (!acc.has(key)) { - acc.set(key, getXValue({point: d, xAxis, xScale})); - } - }); - return acc; - }, new Map()); - - if (xAxis.type === 'category') { - return categories.reduce<[string, number][]>((acc, category) => { - const xValue = xValues.get(category); - if (typeof xValue === 'number') { - acc.push([category, xValue]); - } - - return acc; - }, []); - } - - return sort(Array.from(xValues), ([_x, xValue]) => xValue); -} - -export const prepareAreaData = (args: { - series: PreparedAreaSeries[]; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; - boundsHeight: number; -}): PreparedAreaData[] => { - const {series, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight} = args; - const [_xMin, xRangeMax] = xScale.range(); - const xMax = xRangeMax / (1 - xAxis.maxPadding); - - return Array.from(group(series, (s) => s.stackId)).reduce( - (result, [_stackId, seriesStack]) => { - const xValues = getXValues(seriesStack, xAxis, xScale); - - const accumulatedYValues = new Map(); - xValues.forEach(([key]) => { - accumulatedYValues.set(key, 0); - }); - - const seriesStackData = seriesStack.reduce((acc, s) => { - const yAxisIndex = s.yAxis; - const seriesYAxis = yAxis[yAxisIndex]; - const seriesYScale = yScale[yAxisIndex]; - const yMin = getYValue({point: {y: 0}, yAxis: seriesYAxis, yScale: seriesYScale}); - const seriesData = s.data.reduce>((m, d) => { - const key = String( - xAxis.type === 'category' - ? getDataCategoryValue({ - axisDirection: 'x', - categories: xAxis.categories || [], - data: d, - }) - : d.x, - ); - return m.set(key, d); - }, new Map()); - const points = xValues.reduce((pointsAcc, [x, xValue]) => { - const accumulatedYValue = accumulatedYValues.get(x) || 0; - const d = - seriesData.get(x) || - ({ - x, - // FIXME: think about how to break the series into separate areas(null Y values) - y: 0, - } as AreaSeriesData); - const yValue = - getYValue({point: d, yAxis: seriesYAxis, yScale: seriesYScale}) - - accumulatedYValue; - accumulatedYValues.set(x, yMin - yValue); - - pointsAcc.push({ - y0: yMin - accumulatedYValue, - x: xValue, - y: yValue, - data: d, - series: s, - }); - return pointsAcc; - }, []); - - let labels: LabelData[] = []; - const htmlElements: HtmlItem[] = []; - - if (s.dataLabels.enabled) { - const labelItems = points.map((p) => getLabelData(p, s, xMax)); - if (s.dataLabels.html) { - const htmlLabels = labelItems.map((l) => { - return { - x: l.x - l.size.width / 2, - y: l.y, - content: l.text, - }; - }); - htmlElements.push(...htmlLabels); - } else { - labels = labelItems; - } - } - - let markers: MarkerData[] = []; - if (s.marker.states.normal.enabled || s.marker.states.hover.enabled) { - markers = points.map((p) => ({ - point: p, - active: true, - hovered: false, - })); - } - - acc.push({ - points, - markers, - labels, - color: s.color, - opacity: s.opacity, - width: s.lineWidth, - series: s, - hovered: false, - active: true, - id: s.id, - htmlElements, - }); - - return acc; - }, []); - - if (series.some((s) => s.stacking === 'percent')) { - xValues.forEach(([x], index) => { - const stackHeight = accumulatedYValues.get(x) || 0; - let acc = 0; - const ratio = plotHeight / stackHeight; - - seriesStackData.forEach((item) => { - const point = item.points[index]; - - if (point) { - const height = (point.y0 - point.y) * ratio; - point.y0 = plotHeight - height - acc; - point.y = point.y0 + height; - - acc += height; - } - }); - }); - } - - return result.concat(seriesStackData); - }, - [], - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/area/types.ts b/src/plugins/d3/renderer/hooks/useShapes/area/types.ts deleted file mode 100644 index 065c8d1a..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/area/types.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {AreaSeriesData} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedAreaSeries} from '../../useSeries/types'; - -export type PointData = { - y0: number; - x: number; - y: number; - data: AreaSeriesData; - series: PreparedAreaSeries; -}; - -export type MarkerData = { - point: PointData; - active: boolean; - hovered: boolean; -}; - -export type PreparedAreaData = { - id: string; - points: PointData[]; - markers: MarkerData[]; - color: string; - opacity: number; - width: number; - series: PreparedAreaSeries; - hovered: boolean; - active: boolean; - labels: LabelData[]; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-x/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/bar-x/index.tsx deleted file mode 100644 index 9e232dd0..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-x/index.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import React from 'react'; - -import {color, select} from 'd3'; -import type {Dispatch} from 'd3'; -import get from 'lodash/get'; - -import {block} from '../../../../../../utils/cn'; -import {LabelData} from '../../../types'; -import {filterOverlappingLabels} from '../../../utils'; -import type {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; - -import type {PreparedBarXData} from './types'; - -export {prepareBarXData} from './prepare-data'; -export * from './types'; - -const b = block('d3-bar-x'); - -type Args = { - dispatcher: Dispatch; - preparedData: PreparedBarXData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const BarXSeriesShapes = (args: Args) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - const hoverOptions = get(seriesOptions, 'bar-x.states.hover'); - const inactiveOptions = get(seriesOptions, 'bar-x.states.inactive'); - svgElement.selectAll('*').remove(); - const rectSelection = svgElement - .selectAll('allRects') - .data(preparedData) - .join('rect') - .attr('class', b('segment')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('height', (d) => d.height) - .attr('width', (d) => d.width) - .attr('fill', (d) => d.data.color || d.series.color) - .attr('opacity', (d) => d.opacity) - .attr('cursor', (d) => d.series.cursor); - - let dataLabels = preparedData.map((d) => d.label).filter(Boolean) as LabelData[]; - if (!preparedData[0]?.series.dataLabels.allowOverlap) { - dataLabels = filterOverlappingLabels(dataLabels); - } - - const labelSelection = svgElement - .selectAll('text') - .data(dataLabels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null); - - dispatcher.on('hover-shape.bar-x', (data?: PreparedBarXData[]) => { - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - if (!data) { - if (hoverEnabled) { - rectSelection.attr('fill', (d) => d.data.color || d.series.color); - } - - if (inactiveEnabled) { - rectSelection.attr('opacity', null); - labelSelection.attr('opacity', null); - } - - return; - } - - if (hoverEnabled) { - const hoveredValues = data.map((d) => d.data.x); - rectSelection.attr('fill', (d) => { - const fillColor = d.data.color || d.series.color; - - if (hoveredValues.includes(d.data.x)) { - return ( - color(fillColor)?.brighter(hoverOptions?.brightness).toString() || - fillColor - ); - } - - return fillColor; - }); - } - - if (inactiveEnabled) { - const hoveredSeries = data.map((d) => d.series.id); - rectSelection.attr('opacity', (d) => { - return hoveredSeries.includes(d.series.id) - ? null - : inactiveOptions?.opacity || null; - }); - labelSelection.attr('opacity', (d) => { - return hoveredSeries.includes(d.series.id) - ? null - : inactiveOptions?.opacity || null; - }); - } - }); - - return () => { - dispatcher.on('hover-shape.bar-x', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.ts deleted file mode 100644 index a58bd0dd..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.ts +++ /dev/null @@ -1,209 +0,0 @@ -import {ascending, descending, max, sort} from 'd3'; -import type {ScaleBand, ScaleLinear, ScaleTime} from 'd3'; -import get from 'lodash/get'; - -import type {BarXSeriesData} from '../../../../../../types'; -import {LabelData} from '../../../types'; -import {getDataCategoryValue, getLabelsSize} from '../../../utils'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import type {PreparedBarXSeries, PreparedSeriesOptions} from '../../useSeries/types'; -import {MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH} from '../constants'; - -import {PreparedBarXData} from './types'; - -function getLabelData(d: PreparedBarXData): LabelData | undefined { - if (!d.series.dataLabels.enabled) { - return undefined; - } - - const text = String(d.data.label || d.data.y); - const style = d.series.dataLabels.style; - const html = d.series.dataLabels.html; - const {maxHeight: height, maxWidth: width} = getLabelsSize({ - labels: [text], - style, - html, - }); - - let y = Math.max(height, d.y - d.series.dataLabels.padding); - if (d.series.dataLabels.inside) { - y = d.y + d.height / 2; - } - - const x = d.x + d.width / 2; - return { - text, - x: html ? x - width / 2 : x, - y: html ? y - height : y, - style, - size: {width, height}, - textAnchor: 'middle', - series: d.series, - }; -} - -export const prepareBarXData = (args: { - series: PreparedBarXSeries[]; - seriesOptions: PreparedSeriesOptions; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; - boundsHeight: number; -}): PreparedBarXData[] => { - const {series, seriesOptions, xAxis, xScale, yScale, boundsHeight: plotHeight} = args; - const categories = get(xAxis, 'categories', [] as string[]); - const barMaxWidth = get(seriesOptions, 'bar-x.barMaxWidth'); - const barPadding = get(seriesOptions, 'bar-x.barPadding'); - const groupPadding = get(seriesOptions, 'bar-x.groupPadding'); - const sortingOptions = get(seriesOptions, 'bar-x.dataSorting'); - const comparator = sortingOptions?.direction === 'desc' ? descending : ascending; - const sortKey = (() => { - switch (sortingOptions?.key) { - case 'y': { - return 'data.y'; - } - case 'name': { - return 'series.name'; - } - default: { - return undefined; - } - } - })(); - - const data: Record< - string | number, - Record - > = {}; - series.forEach((s) => { - s.data.forEach((d) => { - const xValue = - xAxis.type === 'category' - ? getDataCategoryValue({axisDirection: 'x', categories, data: d}) - : d.x; - - if (xValue) { - if (!data[xValue]) { - data[xValue] = {}; - } - - const xGroup = data[xValue]; - - if (!xGroup[s.stackId]) { - xGroup[s.stackId] = []; - } - - xGroup[s.stackId].push({data: d, series: s}); - } - }); - }); - - let bandWidth = Infinity; - - if (xAxis.type === 'category') { - const xBandScale = xScale as ScaleBand; - bandWidth = xBandScale.bandwidth(); - } else { - const xLinearScale = xScale as ScaleLinear | ScaleTime; - const xValues = series.reduce((acc, s) => { - s.data.forEach((dataItem) => acc.push(Number(dataItem.x))); - return acc; - }, []); - - xValues.sort().forEach((xValue, index) => { - if (index > 0 && xValue !== xValues[index - 1]) { - const dist = xLinearScale(xValue) - xLinearScale(xValues[index - 1]); - if (dist < bandWidth) { - bandWidth = dist; - } - } - }); - } - - const maxGroupSize = max(Object.values(data), (d) => Object.values(d).length) || 1; - const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP); - const groupWidth = bandWidth - groupGap; - const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP); - const rectWidth = Math.max( - MIN_BAR_WIDTH, - Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth), - ); - - const result: PreparedBarXData[] = []; - - Object.entries(data).forEach(([xValue, val]) => { - const stacks = Object.values(val); - const currentGroupWidth = rectWidth * stacks.length + rectGap * (stacks.length - 1); - stacks.forEach((yValues, groupItemIndex) => { - let stackHeight = 0; - const stackItems: PreparedBarXData[] = []; - - const sortedData = sortKey - ? sort(yValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey))) - : yValues; - sortedData.forEach((yValue) => { - const yAxisIndex = yValue.series.yAxis; - const seriesYScale = yScale[yAxisIndex] as ScaleLinear; - let xCenter; - - if (xAxis.type === 'category') { - const xBandScale = xScale as ScaleBand; - xCenter = (xBandScale(xValue as string) || 0) + xBandScale.bandwidth() / 2; - } else { - const xLinearScale = xScale as - | ScaleLinear - | ScaleTime; - xCenter = xLinearScale(Number(xValue)); - } - - const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex; - const yDataValue = yValue.data.y as number; - const y = seriesYScale(yDataValue); - const base = seriesYScale(0); - const height = yDataValue > 0 ? base - y : y - base; - const barData: PreparedBarXData = { - x, - y: yDataValue > 0 ? y - stackHeight : seriesYScale(0), - width: rectWidth, - height, - opacity: get(yValue.data, 'opacity', null), - data: yValue.data, - series: yValue.series, - htmlElements: [], - }; - - const label = getLabelData(barData); - if (yValue.series.dataLabels.html && label) { - barData.htmlElements.push({ - x: label.x, - y: label.y, - content: label.text, - }); - } else { - barData.label = getLabelData(barData); - } - - stackItems.push(barData); - - stackHeight += height + 1; - }); - - if (series.some((s) => s.stacking === 'percent')) { - let acc = 0; - const ratio = plotHeight / (stackHeight - stackItems.length); - stackItems.forEach((item) => { - item.height = item.height * ratio; - item.y = plotHeight - item.height - acc; - - acc += item.height + 1; - }); - } - - result.push(...stackItems); - }); - }); - - return result; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-x/types.ts b/src/plugins/d3/renderer/hooks/useShapes/bar-x/types.ts deleted file mode 100644 index 4b2431d5..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-x/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {TooltipDataChunkBarX} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedBarXSeries} from '../../useSeries/types'; - -export type PreparedBarXData = Omit & { - x: number; - y: number; - width: number; - height: number; - opacity: number | null; - series: PreparedBarXSeries; - label?: LabelData; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-y/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/bar-y/index.tsx deleted file mode 100644 index 1923f64b..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-y/index.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React from 'react'; - -import {color, select} from 'd3'; -import type {Dispatch} from 'd3'; -import get from 'lodash/get'; - -import {block} from '../../../../../../utils/cn'; -import {LabelData} from '../../../types'; -import type {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; - -import type {PreparedBarYData} from './types'; -export {prepareBarYData} from './prepare-data'; - -const b = block('d3-bar-y'); - -type Args = { - dispatcher: Dispatch; - preparedData: PreparedBarYData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const BarYSeriesShapes = (args: Args) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - const rectSelection = svgElement - .selectAll('rect') - .data(preparedData) - .join('rect') - .attr('class', b('segment')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('height', (d) => d.height) - .attr('width', (d) => d.width) - .attr('fill', (d) => d.color) - .attr('opacity', (d) => d.data.opacity || null) - .attr('cursor', (d) => d.series.cursor); - - const dataLabels = preparedData.reduce((acc, d) => { - if (d.label) { - acc.push(d.label); - } - return acc; - }, []); - const labelSelection = svgElement - .selectAll('text') - .data(dataLabels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null); - - const hoverOptions = get(seriesOptions, 'bar-y.states.hover'); - const inactiveOptions = get(seriesOptions, 'bar-y.states.inactive'); - - dispatcher.on('hover-shape.bar-y', (data?: PreparedBarYData[]) => { - if (hoverOptions?.enabled) { - const hovered = data?.reduce((acc, d) => { - acc.add(d.data.y); - return acc; - }, new Set()); - - rectSelection.attr('fill', (d) => { - const fillColor = d.color; - - if (hovered?.has(d.data.y)) { - return ( - color(fillColor)?.brighter(hoverOptions.brightness).toString() || - fillColor - ); - } - - return fillColor; - }); - } - - if (inactiveOptions?.enabled) { - const hoveredSeries = data?.map((d) => d.series.id); - const newOpacity = (d: PreparedBarYData | LabelData) => { - if (hoveredSeries?.length && !hoveredSeries.includes(d.series.id)) { - return inactiveOptions.opacity || null; - } - - return null; - }; - rectSelection.attr('opacity', newOpacity); - labelSelection.attr('opacity', newOpacity); - } - }); - - return () => { - dispatcher.on('hover-shape.bar-y', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.ts deleted file mode 100644 index 29aacf93..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.ts +++ /dev/null @@ -1,225 +0,0 @@ -import {ascending, descending, max, sort} from 'd3'; -import type {ScaleBand, ScaleLinear, ScaleTime} from 'd3'; -import get from 'lodash/get'; - -import type {BarYSeriesData} from '../../../../../../types'; -import {LabelData} from '../../../types'; -import {getDataCategoryValue, getLabelsSize} from '../../../utils'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import type {PreparedBarYSeries, PreparedSeriesOptions} from '../../useSeries/types'; -import {MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH} from '../constants'; - -import type {PreparedBarYData} from './types'; - -const DEFAULT_LABEL_PADDING = 7; - -function groupByYValue(series: PreparedBarYSeries[], yAxis: PreparedAxis[]) { - const data: Record< - string | number, - Record - > = {}; - series.forEach((s) => { - s.data.forEach((d) => { - const axisIndex = get(s, 'yAxis', 0); - const seriesYAxis = yAxis[axisIndex]; - const categories = get(seriesYAxis, 'categories', [] as string[]); - const key = - seriesYAxis.type === 'category' - ? getDataCategoryValue({axisDirection: 'y', categories, data: d}) - : d.y; - - if (key) { - if (!data[key]) { - data[key] = {}; - } - - if (!data[key][s.stackId]) { - data[key][s.stackId] = []; - } - - data[key][s.stackId].push({data: d, series: s}); - } - }); - }); - - return data; -} - -function getBandWidth(series: PreparedBarYSeries[], yAxis: PreparedAxis[], yScale: ChartScale) { - let bandWidth = Infinity; - - if (yAxis[0].type === 'category') { - bandWidth = (yScale as ScaleBand).bandwidth(); - } else { - const scale = yScale as ScaleLinear | ScaleTime; - const axisValues = series.reduce((acc, s) => { - s.data.forEach((dataItem) => acc.push(Number(dataItem.y))); - return acc; - }, []); - - axisValues.sort().forEach((value, index) => { - if (index > 0 && value !== axisValues[index - 1]) { - const dist = scale(value) - scale(axisValues[index - 1]); - if (dist < bandWidth) { - bandWidth = dist; - } - } - }); - } - - return bandWidth; -} - -function setLabel(prepared: PreparedBarYData) { - const dataLabels = prepared.series.dataLabels; - if (!dataLabels.enabled) { - return; - } - - const data = prepared.data; - const content = String(data.label || data.x); - const {maxHeight: height, maxWidth: width} = getLabelsSize({ - labels: [content], - style: dataLabels.style, - html: dataLabels.html, - }); - const x = dataLabels.inside - ? prepared.x + prepared.width / 2 - : prepared.x + prepared.width + DEFAULT_LABEL_PADDING; - const y = prepared.y + prepared.height / 2; - - if (dataLabels.html) { - prepared.htmlElements.push({ - x, - y: y - height / 2, - content, - }); - } else { - prepared.label = { - x, - y: y + height / 2, - text: content, - textAnchor: dataLabels.inside ? 'middle' : 'right', - style: dataLabels.style, - series: prepared.series, - size: {width, height}, - } as LabelData; - } -} - -export const prepareBarYData = (args: { - series: PreparedBarYSeries[]; - seriesOptions: PreparedSeriesOptions; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; -}): PreparedBarYData[] => { - const { - series, - seriesOptions, - yAxis, - xScale, - yScale: [yScale], - } = args; - - const xLinearScale = xScale as ScaleLinear; - const plotWidth = xLinearScale(xLinearScale.domain()[1]); - const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth'); - const barPadding = get(seriesOptions, 'bar-y.barPadding'); - const groupPadding = get(seriesOptions, 'bar-y.groupPadding'); - const sortingOptions = get(seriesOptions, 'bar-y.dataSorting'); - const comparator = sortingOptions?.direction === 'desc' ? descending : ascending; - const sortKey = (() => { - switch (sortingOptions?.key) { - case 'x': { - return 'data.x'; - } - case 'name': { - return 'series.name'; - } - default: { - return undefined; - } - } - })(); - - const groupedData = groupByYValue(series, yAxis); - const bandWidth = getBandWidth(series, yAxis, yScale); - - const maxGroupSize = max(Object.values(groupedData), (d) => Object.values(d).length) || 1; - const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP); - const groupWidth = bandWidth - groupGap; - const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP); - const barHeight = Math.max( - MIN_BAR_WIDTH, - Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth), - ); - - const result: PreparedBarYData[] = []; - - Object.entries(groupedData).forEach(([yValue, val]) => { - const stacks = Object.values(val); - const currentBarHeight = barHeight * stacks.length + rectGap * (stacks.length - 1); - stacks.forEach((measureValues, groupItemIndex) => { - const base = xLinearScale(0); - let stackSum = base; - - const stackItems: PreparedBarYData[] = []; - const sortedData = sortKey - ? sort(measureValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey))) - : measureValues; - sortedData.forEach(({data, series: s}) => { - let center; - - if (yAxis[0].type === 'category') { - const bandScale = yScale as ScaleBand; - center = (bandScale(yValue as string) || 0) + bandWidth / 2; - } else { - const scale = yScale as ScaleLinear | ScaleTime; - center = scale(Number(yValue)); - } - - const y = center - currentBarHeight / 2 + (barHeight + rectGap) * groupItemIndex; - const xValue = Number(data.x); - const width = - xValue > 0 ? xLinearScale(xValue) - base : base - xLinearScale(xValue); - - const item: PreparedBarYData = { - x: xValue > 0 ? stackSum : stackSum - width, - y, - width, - height: barHeight, - color: data.color || s.color, - opacity: get(data, 'opacity', null), - data, - series: s, - htmlElements: [], - }; - - stackItems.push(item); - stackSum += width + 1; - }); - - if (series.some((s) => s.stacking === 'percent')) { - let acc = 0; - const ratio = plotWidth / (stackSum - stackItems.length); - stackItems.forEach((item) => { - item.width = item.width * ratio; - item.x = acc; - - acc += item.width; - }); - } - - result.push(...stackItems); - }); - }); - - result.forEach((d) => { - setLabel(d); - }); - - return result; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/bar-y/types.ts b/src/plugins/d3/renderer/hooks/useShapes/bar-y/types.ts deleted file mode 100644 index 4b5bfa12..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/bar-y/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {TooltipDataChunkBarX} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedBarYSeries} from '../../useSeries/types'; - -export type PreparedBarYData = Omit & { - x: number; - y: number; - width: number; - height: number; - color: string; - opacity: number | null; - series: PreparedBarYSeries; - label?: LabelData; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/constants.ts b/src/plugins/d3/renderer/hooks/useShapes/constants.ts deleted file mode 100644 index f336db01..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const MIN_BAR_WIDTH = 1; -export const MIN_BAR_GAP = 1; -export const MIN_BAR_GROUP_GAP = 1; diff --git a/src/plugins/d3/renderer/hooks/useShapes/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/index.tsx deleted file mode 100644 index c1582253..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/index.tsx +++ /dev/null @@ -1,283 +0,0 @@ -import React from 'react'; - -import {Dispatch, group} from 'd3'; - -import type { - PreparedAreaSeries, - PreparedBarXSeries, - PreparedBarYSeries, - PreparedLineSeries, - PreparedPieSeries, - PreparedScatterSeries, - PreparedSeries, - PreparedSeriesOptions, - PreparedSplit, - PreparedTreemapSeries, - PreparedWaterfallSeries, -} from '../'; -import {getOnlyVisibleSeries} from '../../utils'; -import type {ChartScale} from '../useAxisScales'; -import type {PreparedAxis} from '../useChartOptions/types'; - -import {AreaSeriesShapes} from './area'; -import {prepareAreaData} from './area/prepare-data'; -import type {PreparedAreaData} from './area/types'; -import {BarXSeriesShapes, prepareBarXData} from './bar-x'; -import type {PreparedBarXData} from './bar-x'; -import {BarYSeriesShapes, prepareBarYData} from './bar-y'; -import type {PreparedBarYData} from './bar-y/types'; -import {LineSeriesShapes} from './line'; -import {prepareLineData} from './line/prepare-data'; -import type {PreparedLineData} from './line/types'; -import {PieSeriesShapes} from './pie'; -import {preparePieData} from './pie/prepare-data'; -import type {PreparedPieData} from './pie/types'; -import {ScatterSeriesShape, prepareScatterData} from './scatter'; -import type {PreparedScatterData} from './scatter/types'; -export type {PreparedBarXData} from './bar-x'; -export type {PreparedScatterData} from './scatter/types'; -import {TreemapSeriesShape} from './treemap'; -import {prepareTreemapData} from './treemap/prepare-data'; -import {PreparedWaterfallData, WaterfallSeriesShapes, prepareWaterfallData} from './waterfall'; - -import './styles.scss'; - -export type ShapeData = - | PreparedBarXData - | PreparedBarYData - | PreparedScatterData - | PreparedLineData - | PreparedPieData - | PreparedAreaData - | PreparedWaterfallData; - -type Args = { - boundsWidth: number; - boundsHeight: number; - dispatcher: Dispatch; - series: PreparedSeries[]; - seriesOptions: PreparedSeriesOptions; - xAxis: PreparedAxis; - yAxis: PreparedAxis[]; - xScale?: ChartScale; - yScale?: ChartScale[]; - split: PreparedSplit; - htmlLayout: HTMLElement | null; -}; - -export const useShapes = (args: Args) => { - const { - boundsWidth, - boundsHeight, - dispatcher, - series, - seriesOptions, - xAxis, - xScale, - yAxis, - yScale, - split, - htmlLayout, - } = args; - - const shapesComponents = React.useMemo(() => { - const visibleSeries = getOnlyVisibleSeries(series); - const groupedSeries = group(visibleSeries, (item) => item.type); - const shapesData: ShapeData[] = []; - const shapes = Array.from(groupedSeries).reduce((acc, item) => { - const [seriesType, chartSeries] = item; - switch (seriesType) { - case 'bar-x': { - if (xScale && yScale) { - const preparedData = prepareBarXData({ - series: chartSeries as PreparedBarXSeries[], - seriesOptions, - xAxis, - xScale, - yAxis, - yScale, - boundsHeight, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'bar-y': { - if (xScale && yScale) { - const preparedData = prepareBarYData({ - series: chartSeries as PreparedBarYSeries[], - seriesOptions, - xAxis, - xScale, - yAxis, - yScale, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'waterfall': { - if (xScale && yScale) { - const preparedData = prepareWaterfallData({ - series: chartSeries as PreparedWaterfallSeries[], - seriesOptions, - xAxis, - xScale, - yAxis, - yScale, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'line': { - if (xScale && yScale) { - const preparedData = prepareLineData({ - series: chartSeries as PreparedLineSeries[], - xAxis, - xScale, - yAxis, - yScale, - split, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'area': { - if (xScale && yScale) { - const preparedData = prepareAreaData({ - series: chartSeries as PreparedAreaSeries[], - xAxis, - xScale, - yAxis, - yScale, - boundsHeight, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'scatter': { - if (xScale && yScale) { - const preparedData = prepareScatterData({ - series: chartSeries as PreparedScatterSeries[], - xAxis, - xScale, - yAxis, - yScale, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - } - break; - } - case 'pie': { - const preparedData = preparePieData({ - series: chartSeries as PreparedPieSeries[], - boundsWidth, - boundsHeight, - }); - acc.push( - , - ); - shapesData.push(...preparedData); - break; - } - case 'treemap': { - const preparedData = prepareTreemapData({ - // We should have exactly one series with "treemap" type - // Otherwise data validation should emit an error - series: chartSeries[0] as PreparedTreemapSeries, - width: boundsWidth, - height: boundsHeight, - }); - acc.push( - , - ); - shapesData.push(preparedData as unknown as ShapeData); - } - } - return acc; - }, []); - - return {shapes, shapesData}; - }, [ - boundsWidth, - boundsHeight, - dispatcher, - series, - seriesOptions, - xAxis, - xScale, - yAxis, - yScale, - ]); - - return {shapes: shapesComponents.shapes, shapesData: shapesComponents.shapesData}; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/line/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/line/index.tsx deleted file mode 100644 index 714a09a7..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/line/index.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import React from 'react'; - -import type {BaseType, Dispatch} from 'd3'; -import {color, line as lineGenerator, select} from 'd3'; -import get from 'lodash/get'; - -import type {TooltipDataChunkLine} from '../../../../../../types'; -import {block} from '../../../../../../utils/cn'; -import type {LabelData} from '../../../types'; -import {filterOverlappingLabels} from '../../../utils'; -import type {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; -import { - getMarkerHaloVisibility, - getMarkerVisibility, - renderMarker, - selectMarkerHalo, - selectMarkerSymbol, - setMarker, -} from '../marker'; -import {getLineDashArray, setActiveState} from '../utils'; - -import type {MarkerData, PointData, PreparedLineData} from './types'; - -const b = block('d3-line'); - -type Args = { - dispatcher: Dispatch; - preparedData: PreparedLineData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const LineSeriesShapes = (args: Args) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - const hoverOptions = get(seriesOptions, 'line.states.hover'); - const inactiveOptions = get(seriesOptions, 'line.states.inactive'); - - const line = lineGenerator() - .x((d) => d.x) - .y((d) => d.y); - - svgElement.selectAll('*').remove(); - - const lineSelection = svgElement - .selectAll('path') - .data(preparedData) - .join('path') - .attr('d', (d) => line(d.points)) - .attr('fill', 'none') - .attr('stroke', (d) => d.color) - .attr('stroke-width', (d) => d.width) - .attr('stroke-linejoin', (d) => d.linecap) - .attr('stroke-linecap', (d) => d.linecap) - .attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.width)) - .attr('opacity', (d) => d.opacity) - .attr('cursor', (d) => d.series.cursor); - - let dataLabels = preparedData.reduce((acc, d) => { - return acc.concat(d.labels); - }, [] as LabelData[]); - - if (!preparedData[0]?.series.dataLabels.allowOverlap) { - dataLabels = filterOverlappingLabels(dataLabels); - } - - const labelsSelection = svgElement - .selectAll('text') - .data(dataLabels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null); - - const markers = preparedData.reduce((acc, d) => acc.concat(d.markers), []); - const markerSelection = svgElement - .selectAll('marker') - .data(markers) - .join('g') - .call(renderMarker); - - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - dispatcher.on('hover-shape.line', (data?: TooltipDataChunkLine[]) => { - const selected = data?.filter((d) => d.series.type === 'line') || []; - const selectedDataItems = selected.map((d) => d.data); - const selectedSeriesIds = selected.map((d) => d.series?.id); - - lineSelection.datum((d, index, list) => { - const elementSelection = select(list[index]); - - const hovered = Boolean(hoverEnabled && selectedSeriesIds.includes(d.id)); - if (d.hovered !== hovered) { - d.hovered = hovered; - elementSelection.attr('stroke', (d) => { - const initialColor = d.color || ''; - if (d.hovered) { - return ( - color(initialColor) - ?.brighter(hoverOptions?.brightness) - .toString() || initialColor - ); - } - return initialColor; - }); - } - - return setActiveState({ - element: list[index], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.id), - ), - datum: d, - }); - }); - - labelsSelection.datum((d, index, list) => { - return setActiveState({ - element: list[index], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.series.id), - ), - datum: d, - }); - }); - - markerSelection.datum((d, index, list) => { - const elementSelection = select(list[index]); - - const hovered = Boolean(hoverEnabled && selectedDataItems.includes(d.point.data)); - if (d.hovered !== hovered) { - d.hovered = hovered; - elementSelection.attr('visibility', getMarkerVisibility(d)); - selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility); - selectMarkerSymbol(elementSelection).call( - setMarker, - hovered ? 'hover' : 'normal', - ); - } - - if (d.point.series.marker.states.normal.enabled) { - const isActive = Boolean( - !inactiveEnabled || - !selectedSeriesIds.length || - selectedSeriesIds.includes(d.point.series.id), - ); - setActiveState({ - element: list[index], - state: inactiveOptions, - active: isActive, - datum: d, - }); - } - return d; - }); - }); - - return () => { - dispatcher.on('hover-shape.line', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/line/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/line/prepare-data.ts deleted file mode 100644 index 777b95cc..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/line/prepare-data.ts +++ /dev/null @@ -1,115 +0,0 @@ -import type {HtmlItem, LabelData} from '../../../types'; -import {getLabelsSize, getLeftPosition} from '../../../utils'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import type {PreparedLineSeries} from '../../useSeries/types'; -import type {PreparedSplit} from '../../useSplit/types'; -import {getXValue, getYValue} from '../utils'; - -import type {MarkerData, PointData, PreparedLineData} from './types'; - -function getLabelData(point: PointData, series: PreparedLineSeries, xMax: number) { - const text = String(point.data.label || point.data.y); - const style = series.dataLabels.style; - const size = getLabelsSize({labels: [text], style}); - - const labelData: LabelData = { - text, - x: point.x, - y: point.y - series.dataLabels.padding, - style, - size: {width: size.maxWidth, height: size.maxHeight}, - textAnchor: 'middle', - series: series, - active: true, - }; - - const left = getLeftPosition(labelData); - if (left < 0) { - labelData.x = labelData.x + Math.abs(left); - } else { - const right = left + labelData.size.width; - if (right > xMax) { - labelData.x = labelData.x - xMax - right; - } - } - - return labelData; -} - -function getHtmlLabel(point: PointData, series: PreparedLineSeries, xMax: number): HtmlItem { - const content = String(point.data.label || point.data.y); - const size = getLabelsSize({labels: [content], html: true}); - - return { - x: Math.min(xMax - size.maxWidth, Math.max(0, point.x)), - y: Math.max(0, point.y - series.dataLabels.padding - size.maxHeight), - content, - }; -} - -export const prepareLineData = (args: { - series: PreparedLineSeries[]; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; - split: PreparedSplit; -}): PreparedLineData[] => { - const {series, xAxis, yAxis, xScale, yScale, split} = args; - const [_xMin, xRangeMax] = xScale.range(); - const xMax = xRangeMax / (1 - xAxis.maxPadding); - - return series.reduce((acc, s) => { - const yAxisIndex = s.yAxis; - const seriesYAxis = yAxis[yAxisIndex]; - const yAxisTop = split.plots[seriesYAxis.plotIndex]?.top || 0; - const seriesYScale = yScale[s.yAxis]; - const points = s.data.map((d) => ({ - x: getXValue({point: d, xAxis, xScale}), - y: yAxisTop + getYValue({point: d, yAxis: seriesYAxis, yScale: seriesYScale}), - active: true, - data: d, - series: s, - })); - - const htmlElements: HtmlItem[] = []; - let labels: LabelData[] = []; - if (s.dataLabels.enabled) { - if (s.dataLabels.html) { - htmlElements.push(...points.map((p) => getHtmlLabel(p, s, xMax))); - } else { - labels = points.map((p) => getLabelData(p, s, xMax)); - } - } - - let markers: MarkerData[] = []; - if (s.marker.states.normal.enabled || s.marker.states.hover.enabled) { - markers = points.map((p) => ({ - point: p, - active: true, - hovered: false, - })); - } - - const result: PreparedLineData = { - points, - markers, - labels, - color: s.color, - width: s.lineWidth, - series: s, - hovered: false, - active: true, - id: s.id, - dashStyle: s.dashStyle, - linecap: s.linecap, - opacity: s.opacity, - htmlElements, - }; - - acc.push(result); - - return acc; - }, []); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/line/types.ts b/src/plugins/d3/renderer/hooks/useShapes/line/types.ts deleted file mode 100644 index 11fe8133..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/line/types.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {DashStyle, LineCap} from '../../../../../../constants'; -import {LineSeriesData} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedLineSeries} from '../../useSeries/types'; - -export type PointData = { - x: number; - y: number; - data: LineSeriesData; - series: PreparedLineSeries; -}; - -export type MarkerData = { - point: PointData; - active: boolean; - hovered: boolean; -}; - -export type PreparedLineData = { - id: string; - points: PointData[]; - markers: MarkerData[]; - color: string; - width: number; - series: PreparedLineSeries; - hovered: boolean; - active: boolean; - labels: LabelData[]; - dashStyle: DashStyle; - linecap: LineCap; - opacity: number | null; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/marker.ts b/src/plugins/d3/renderer/hooks/useShapes/marker.ts deleted file mode 100644 index 2ac8e753..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/marker.ts +++ /dev/null @@ -1,99 +0,0 @@ -import {BaseType, Selection, symbol} from 'd3'; -import get from 'lodash/get'; - -import {SymbolType} from '../../../../../constants'; -import {block} from '../../../../../utils/cn'; -import {getSymbol} from '../../utils'; - -import {MarkerData as AreaMarkerData} from './area/types'; -import {MarkerData as LineMarkerData} from './line/types'; -import {MarkerData as ScatterMarkerData} from './scatter/types'; - -const b = block('d3-marker'); -const haloClassName = b('halo'); -const symbolClassName = b('symbol'); - -type MarkerData = LineMarkerData | AreaMarkerData | ScatterMarkerData; - -export function renderMarker( - selection: Selection, -) { - const markerSelection = selection - .attr('class', b('wrapper')) - .attr('visibility', getMarkerVisibility) - .attr('transform', (d) => { - return `translate(${d.point.x},${d.point.y})`; - }); - markerSelection - .append('path') - .attr('class', haloClassName) - .attr('d', (d) => { - const series = d.point.series; - const type = series.marker.states.normal.symbol; - const radius = get(d.point.data, 'radius', series.marker.states.hover.radius); - const haloSize = series.marker.states.hover.halo.size; - return getMarkerSymbol(type, radius + haloSize); - }) - .attr('fill', (d) => d.point.series.color) - .attr('opacity', (d) => d.point.series.marker.states.hover.halo.opacity) - .attr('z-index', -1) - .attr('visibility', getMarkerHaloVisibility); - markerSelection - .append('path') - .attr('class', symbolClassName) - .call(setMarker, 'normal') - .attr('fill', (d) => d.point.series.color); - - return markerSelection; -} - -export function getMarkerVisibility(d: MarkerData) { - const markerStates = d.point.series.marker.states; - let enabled: Boolean; - - if (d.hovered) { - enabled = markerStates.hover.enabled && d.hovered; - } else { - enabled = - markerStates.normal.enabled || get(d.point.data, 'marker.states.normal.enabled', false); - } - - return enabled ? '' : 'hidden'; -} - -export function getMarkerHaloVisibility(d: MarkerData) { - const markerStates = d.point.series.marker.states; - const enabled = markerStates.hover.halo.enabled && d.hovered; - return enabled ? '' : 'hidden'; -} - -export function setMarker( - selection: Selection, - state: 'normal' | 'hover', -) { - selection - .attr('d', (d) => { - const series = d.point.series; - const type = series.marker.states.normal.symbol; - const radius = get(d.point.data, 'radius', series.marker.states[state].radius); - const size = radius + series.marker.states[state].borderWidth; - return getMarkerSymbol(type, size); - }) - .attr('stroke-width', (d) => d.point.series.marker.states[state].borderWidth) - .attr('stroke', (d) => d.point.series.marker.states[state].borderColor); -} - -export function getMarkerSymbol(type: `${SymbolType}` = SymbolType.Circle, radius: number) { - const symbolFn = getSymbol(type); - const size = Math.pow(radius, 2) * Math.PI; - - return symbol(symbolFn, size)(); -} - -export function selectMarkerHalo(parentSelection: Selection) { - return parentSelection.select(`.${haloClassName}`); -} - -export function selectMarkerSymbol(parentSelection: Selection) { - return parentSelection.select(`.${symbolClassName}`); -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/pie/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/pie/index.tsx deleted file mode 100644 index 7ad65059..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/pie/index.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import React from 'react'; - -import {arc, color, select} from 'd3'; -import type {BaseType, Dispatch, PieArcDatum} from 'd3'; -import get from 'lodash/get'; - -import {TooltipDataChunkPie} from '../../../../../../types'; -import {block} from '../../../../../../utils/cn'; -import {setEllipsisForOverflowTexts} from '../../../utils'; -import {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; -import {PreparedLineData} from '../line/types'; -import {setActiveState} from '../utils'; - -import {PieLabelData, PreparedPieData, SegmentData} from './types'; - -const b = block('d3-pie'); - -type PreparePieSeriesArgs = { - dispatcher: Dispatch; - preparedData: PreparedPieData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export function getHaloVisibility(d: PieArcDatum) { - const enabled = d.data.pie.halo.enabled && d.data.hovered; - return enabled ? '' : 'hidden'; -} - -export function PieSeriesShapes(args: PreparePieSeriesArgs) { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - const segmentSelector = `.${b('segment')}`; - const connectorSelector = `.${b('connector')}`; - - const shapesSelection = svgElement - .selectAll('pie') - .data(preparedData) - .join('g') - .attr('id', (pieData) => pieData.id) - .attr('class', b('item')) - .attr('transform', (pieData) => { - const [x, y] = pieData.center; - return `translate(${x}, ${y})`; - }) - .style('stroke', (pieData) => pieData.borderColor) - .style('stroke-width', (pieData) => pieData.borderWidth) - .attr('cursor', (pieData) => pieData.series.cursor); - - // Render halo appearing outside the hovered slice - shapesSelection - .selectAll('halo') - .data((pieData) => { - if (pieData.halo.enabled) { - return pieData.segments; - } - return []; - }) - .join('path') - .attr('d', (d) => { - const arcGenerator = arc>() - .innerRadius(d.data.pie.innerRadius) - .outerRadius(d.data.pie.radius + d.data.pie.halo.size) - .cornerRadius(d.data.pie.borderRadius); - return arcGenerator(d); - }) - .attr('class', b('halo')) - .attr('fill', (d) => d.data.color) - .attr('opacity', (d) => d.data.pie.halo.opacity) - .attr('z-index', -1) - .attr('visibility', getHaloVisibility); - - // Render segments - shapesSelection - .selectAll(segmentSelector) - .data((pieData) => pieData.segments) - .join('path') - .attr('d', (d) => { - const arcGenerator = arc>() - .innerRadius(d.data.pie.innerRadius) - .outerRadius(d.data.pie.radius) - .cornerRadius(d.data.pie.borderRadius); - return arcGenerator(d); - }) - .attr('class', b('segment')) - .attr('fill', (d) => d.data.color) - .attr('opacity', (d) => d.data.opacity); - - // render Labels - shapesSelection - .selectAll('text') - .data((pieData) => pieData.labels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null) - .call(setEllipsisForOverflowTexts, (d) => - d.size.width > d.maxWidth ? d.maxWidth : Infinity, - ); - - // Add the polyline between chart and labels - shapesSelection - .selectAll(connectorSelector) - .data((pieData) => pieData.connectors) - .enter() - .append('path') - .attr('class', b('connector')) - .attr('d', (d) => d.path) - .attr('stroke', (d) => d.color) - .attr('stroke-width', 1) - .attr('stroke-linejoin', 'round') - .attr('stroke-linecap', 'round') - .style('fill', 'none'); - - // Render custom shapes if defined - shapesSelection.each(function (d, index, nodes) { - const customShape = d.series.renderCustomShape?.({ - series: { - innerRadius: d.innerRadius, - }, - }); - - if (customShape) { - (nodes[index] as Element).append(customShape as Node); - } - }); - - const eventName = `hover-shape.pie`; - const hoverOptions = get(seriesOptions, 'pie.states.hover'); - const inactiveOptions = get(seriesOptions, 'pie.states.inactive'); - - dispatcher.on(eventName, (data?: TooltipDataChunkPie[]) => { - const selectedSeriesId = data?.[0]?.series?.id; - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - shapesSelection.datum((_d, index, list) => { - const pieSelection = select(list[index]); - const haloSelection = pieSelection.selectAll>( - `.${b('halo')}`, - ); - - pieSelection - .selectAll>(segmentSelector) - .datum((d, i, elements) => { - const hovered = Boolean( - hoverEnabled && d.data.series.id === selectedSeriesId, - ); - if (d.data.hovered !== hovered) { - d.data.hovered = hovered; - select(elements[i]).attr('fill', () => { - const initialColor = d.data.color; - if (d.data.hovered) { - return ( - color(initialColor) - ?.brighter(hoverOptions?.brightness) - .toString() || initialColor - ); - } - return initialColor; - }); - - const currentSegmentHalo = haloSelection.nodes()[i]; - select>(currentSegmentHalo).attr( - 'visibility', - getHaloVisibility, - ); - } - - setActiveState({ - element: elements[i], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesId || - selectedSeriesId === d.data.series.id, - ), - datum: d.data, - }); - - return d; - }); - const labelSelection = pieSelection.selectAll('tspan'); - const connectorSelection = pieSelection.selectAll( - connectorSelector, - ); - labelSelection.merge(connectorSelection).datum((d, i, elements) => { - return setActiveState({ - element: elements[i], - state: inactiveOptions, - active: Boolean( - !inactiveEnabled || - !selectedSeriesId || - selectedSeriesId === d.series.id, - ), - datum: d, - }); - }); - }); - }); - - return () => { - dispatcher.on(eventName, null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/pie/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/pie/prepare-data.ts deleted file mode 100644 index 7bd2b000..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/pie/prepare-data.ts +++ /dev/null @@ -1,256 +0,0 @@ -import {PieArcDatum, arc, group, line as lineGenerator} from 'd3'; - -import {PieSeries} from '../../../../../../types'; -import { - calculateNumericProperty, - getLabelsSize, - getLeftPosition, - isLabelsOverlapping, -} from '../../../utils'; -import {PreparedPieSeries} from '../../useSeries/types'; - -import {PieLabelData, PreparedPieData, SegmentData} from './types'; -import {getCurveFactory, pieGenerator} from './utils'; - -const FULL_CIRCLE = Math.PI * 2; - -type Args = { - series: PreparedPieSeries[]; - boundsWidth: number; - boundsHeight: number; -}; - -const getCenter = ( - boundsWidth: number, - boundsHeight: number, - center?: PieSeries['center'], -): [number, number] => { - const defaultX = boundsWidth * 0.5; - const defaultY = boundsHeight * 0.5; - - if (!center) { - return [defaultX, defaultY]; - } - - const [x, y] = center; - const resultX = calculateNumericProperty({value: x, base: boundsWidth}) ?? defaultX; - const resultY = calculateNumericProperty({value: y, base: boundsHeight}) ?? defaultY; - - return [resultX, resultY]; -}; - -export function preparePieData(args: Args): PreparedPieData[] { - const {series: preparedSeries, boundsWidth, boundsHeight} = args; - const maxRadius = Math.min(boundsWidth, boundsHeight) / 2; - - const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId); - return Array.from(groupedPieSeries).map(([stackId, items]) => { - const series = items[0]; - const { - center, - borderWidth, - borderColor, - borderRadius, - radius: seriesRadius, - innerRadius: seriesInnerRadius, - dataLabels, - } = series; - const radius = - calculateNumericProperty({value: seriesRadius, base: maxRadius}) ?? maxRadius; - - const data: PreparedPieData = { - id: stackId, - center: getCenter(boundsWidth, boundsHeight, center), - innerRadius: calculateNumericProperty({value: seriesInnerRadius, base: radius}) ?? 0, - radius, - segments: [], - labels: [], - connectors: [], - borderColor, - borderWidth, - borderRadius, - series: items[0], - connectorCurve: dataLabels.connectorCurve, - halo: { - enabled: series.states.hover.halo.enabled, - opacity: series.states.hover.halo.opacity, - size: series.states.hover.halo.size, - }, - htmlElements: [], - }; - - const segments = items.map((item) => { - return { - value: item.value, - color: item.color, - opacity: item.opacity, - series: item, - hovered: false, - active: true, - pie: data, - }; - }); - data.segments = pieGenerator(segments); - - let line = lineGenerator(); - const curveFactory = getCurveFactory(data); - if (curveFactory) { - line = line.curve(curveFactory); - } - - if (dataLabels.enabled) { - const {style, connectorPadding, distance} = dataLabels; - const {maxHeight: labelHeight} = getLabelsSize({labels: ['Some Label'], style}); - const minSegmentRadius = maxRadius - connectorPadding - distance - labelHeight; - if (data.radius > minSegmentRadius) { - data.radius = minSegmentRadius; - data.innerRadius = - calculateNumericProperty({value: seriesInnerRadius, base: data.radius}) ?? 0; - } - const connectorStartPointGenerator = arc>() - .innerRadius(data.radius) - .outerRadius(data.radius); - const connectorMidPointRadius = data.radius + distance / 2; - const connectorMidPointGenerator = arc>() - .innerRadius(connectorMidPointRadius) - .outerRadius(connectorMidPointRadius); - const connectorArcRadius = data.radius + distance; - const connectorEndPointGenerator = arc>() - .innerRadius(connectorArcRadius) - .outerRadius(connectorArcRadius); - const labelArcRadius = connectorArcRadius + connectorPadding; - const labelArcGenerator = arc>() - .innerRadius(labelArcRadius) - .outerRadius(labelArcRadius); - - const labels: PieLabelData[] = []; - items.forEach((d, index) => { - const prevLabel = labels[labels.length - 1]; - const text = String(d.data.label || d.data.value); - const shouldUseHtml = dataLabels.html; - const labelSize = getLabelsSize({labels: [text], style, html: shouldUseHtml}); - const labelWidth = labelSize.maxWidth; - const relatedSegment = data.segments[index]; - - const getLabelPosition = (angle: number) => { - let [x, y] = labelArcGenerator.centroid({ - ...relatedSegment, - startAngle: angle, - endAngle: angle, - }); - - y = y < 0 ? y - labelHeight : y; - - if (shouldUseHtml) { - x = x < 0 ? x - labelWidth : x; - } - - x = Math.max(-boundsWidth / 2, x); - - return [x, y]; - }; - - const getConnectorPoints = (angle: number) => { - const connectorStartPoint = - connectorStartPointGenerator.centroid(relatedSegment); - const connectorEndPoint = connectorEndPointGenerator.centroid({ - ...relatedSegment, - startAngle: angle, - endAngle: angle, - }); - - if (dataLabels.connectorShape === 'straight-line') { - return [connectorStartPoint, connectorEndPoint]; - } - - const connectorMidPoint = connectorMidPointGenerator.centroid(relatedSegment); - return [connectorStartPoint, connectorMidPoint, connectorEndPoint]; - }; - - const midAngle = Math.max( - prevLabel?.angle || 0, - relatedSegment.startAngle + - (relatedSegment.endAngle - relatedSegment.startAngle) / 2, - ); - const [x, y] = getLabelPosition(midAngle); - const label: PieLabelData = { - text, - x, - y, - style, - size: {width: labelWidth, height: labelHeight}, - maxWidth: labelWidth, - textAnchor: midAngle < Math.PI ? 'start' : 'end', - series: {id: d.id}, - active: true, - segment: relatedSegment.data, - angle: midAngle, - }; - - let overlap = false; - if (prevLabel) { - overlap = isLabelsOverlapping(prevLabel, label, dataLabels.padding); - - if (overlap) { - let shouldAdjustAngle = true; - - const step = Math.PI / 180; - while (shouldAdjustAngle) { - const newAngle = label.angle + step; - if ( - newAngle > FULL_CIRCLE && - newAngle % FULL_CIRCLE > labels[0].angle - ) { - shouldAdjustAngle = false; - } else { - label.angle = newAngle; - const [newX, newY] = getLabelPosition(newAngle); - - label.x = newX; - label.y = newY; - - if (!isLabelsOverlapping(prevLabel, label, dataLabels.padding)) { - shouldAdjustAngle = false; - overlap = false; - } - } - } - } - } - - if (dataLabels.allowOverlap || !overlap) { - const left = getLeftPosition(label); - - if (Math.abs(left) > boundsWidth / 2) { - label.maxWidth = label.size.width - (Math.abs(left) - boundsWidth / 2); - } else { - const right = left + label.size.width; - if (right > boundsWidth / 2) { - label.maxWidth = label.size.width - (right - boundsWidth / 2); - } - } - - if (shouldUseHtml) { - data.htmlElements.push({ - x: boundsWidth / 2 + label.x, - y: boundsHeight / 2 + label.y, - content: label.text, - }); - } else { - labels.push(label); - } - - const connector = { - path: line(getConnectorPoints(midAngle)), - color: relatedSegment.data.color, - }; - data.connectors.push(connector); - } - }); - - data.labels = labels; - } - - return data; - }); -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/pie/types.ts b/src/plugins/d3/renderer/hooks/useShapes/pie/types.ts deleted file mode 100644 index 876b173b..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/pie/types.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type {PieArcDatum} from 'd3'; - -import {ConnectorCurve} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedPieSeries} from '../../useSeries/types'; - -export type SegmentData = { - value: number; - color: string; - opacity: number | null; - series: PreparedPieSeries; - hovered: boolean; - active: boolean; - pie: PreparedPieData; -}; - -export type PieLabelData = LabelData & { - segment: SegmentData; - angle: number; - maxWidth: number; -}; - -export type PieConnectorData = { - path: string | null; - color: string; -}; - -export type PreparedPieData = { - id: string; - segments: PieArcDatum[]; - labels: PieLabelData[]; - connectors: PieConnectorData[]; - center: [number, number]; - radius: number; - innerRadius: number; - borderRadius: number; - borderWidth: number; - borderColor: string; - series: PreparedPieSeries; - connectorCurve: ConnectorCurve; - halo: { - enabled: boolean; - opacity: number; - size: number; - }; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/pie/utils.ts b/src/plugins/d3/renderer/hooks/useShapes/pie/utils.ts deleted file mode 100644 index 47f40619..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/pie/utils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type {CurveFactory} from 'd3'; -import {curveBasis, curveLinear, pie} from 'd3'; - -import type {PreparedPieData, SegmentData} from './types'; - -export const pieGenerator = pie() - .value((d) => d.value) - .sort(null); - -export function getCurveFactory(data: PreparedPieData): CurveFactory | undefined { - switch (data.connectorCurve) { - case 'basic': { - return curveBasis; - } - case 'linear': { - return curveLinear; - } - } - return undefined; -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/scatter/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/scatter/index.tsx deleted file mode 100644 index 95dedb3e..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/scatter/index.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import React from 'react'; - -import {select} from 'd3'; -import type {BaseType, Dispatch} from 'd3'; -import get from 'lodash/get'; - -import {TooltipDataChunkScatter} from '../../../../../../types'; -import {block} from '../../../../../../utils/cn'; -import {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; -import { - getMarkerHaloVisibility, - renderMarker, - selectMarkerHalo, - selectMarkerSymbol, - setMarker, -} from '../marker'; -import {setActiveState, shapeKey} from '../utils'; - -import type {MarkerData, PreparedScatterData} from './types'; -export {prepareScatterData} from './prepare-data'; - -type ScatterSeriesShapeProps = { - dispatcher: Dispatch; - preparedData: PreparedScatterData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -const b = block('d3-scatter'); - -export function ScatterSeriesShape(props: ScatterSeriesShapeProps) { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = props; - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - const hoverOptions = get(seriesOptions, 'scatter.states.hover'); - const inactiveOptions = get(seriesOptions, 'scatter.states.inactive'); - - svgElement.selectAll('*').remove(); - - const selection = svgElement - .selectAll('path') - .data(preparedData, shapeKey) - .join('g') - .call(renderMarker) - .attr('fill', (d) => d.point.data.color || d.point.series.color || '') - .attr('opacity', (d) => d.point.opacity) - .attr('cursor', (d) => d.point.series.cursor); - - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - dispatcher.on('hover-shape.scatter', (data?: TooltipDataChunkScatter[]) => { - const selected = data?.find((d) => d.series.type === 'scatter'); - const selectedDataItem = selected?.data; - const selectedSeriesId = selected?.series?.id; - - selection.datum((d, index, list) => { - const elementSelection = select(list[index]); - - const hovered = Boolean(hoverEnabled && d.point.data === selectedDataItem); - if (d.hovered !== hovered) { - d.hovered = hovered; - elementSelection.attr('z-index', hovered ? 999 : null); - selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility); - selectMarkerSymbol(elementSelection).call( - setMarker, - hovered ? 'hover' : 'normal', - ); - } - - if (hovered) { - elementSelection.raise(); - } - - if (d.point.series.marker.states.normal.enabled) { - const isActive = Boolean( - !inactiveEnabled || - !selectedSeriesId || - selectedSeriesId === d.point.series.id, - ); - setActiveState({ - element: list[index], - state: inactiveOptions, - active: isActive, - datum: d, - }); - } - return d; - }); - }); - - return () => { - dispatcher.on('hover-shape.scatter', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.ts deleted file mode 100644 index 30716b1a..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.ts +++ /dev/null @@ -1,50 +0,0 @@ -import get from 'lodash/get'; - -import type {ScatterSeriesData} from '../../../../../../types'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import {PreparedScatterSeries} from '../../useSeries/types'; -import {getXValue, getYValue} from '../utils'; - -import {PreparedScatterData} from './types'; - -const getFilteredLinearScatterData = (data: ScatterSeriesData[]) => { - return data.filter((d) => typeof d.x === 'number' && typeof d.y === 'number'); -}; - -export const prepareScatterData = (args: { - series: PreparedScatterSeries[]; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; -}): PreparedScatterData[] => { - const {series, xAxis, xScale, yAxis, yScale} = args; - - return series.reduce((acc, s) => { - const yAxisIndex = get(s, 'yAxis', 0); - const seriesYAxis = yAxis[yAxisIndex]; - const seriesYScale = yScale[yAxisIndex]; - const filteredData = - xAxis.type === 'category' || seriesYAxis.type === 'category' - ? s.data - : getFilteredLinearScatterData(s.data); - - filteredData.forEach((d) => { - acc.push({ - point: { - data: d, - series: s, - x: getXValue({point: d, xAxis, xScale}), - y: getYValue({point: d, yAxis: seriesYAxis, yScale: seriesYScale}), - opacity: get(d, 'opacity', null), - }, - hovered: false, - active: true, - htmlElements: [], - }); - }); - - return acc; - }, []); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/scatter/types.ts b/src/plugins/d3/renderer/hooks/useShapes/scatter/types.ts deleted file mode 100644 index 78767fa1..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/scatter/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {ScatterSeriesData} from '../../../../../../types'; -import {HtmlItem} from '../../../types'; -import {PreparedScatterSeries} from '../../useSeries/types'; - -type PointData = { - x: number; - y: number; - opacity: number | null; - data: ScatterSeriesData; - series: PreparedScatterSeries; -}; - -export type MarkerData = { - point: PointData; - active: boolean; - hovered: boolean; - htmlElements: HtmlItem[]; -}; - -export type PreparedScatterData = MarkerData; diff --git a/src/plugins/d3/renderer/hooks/useShapes/styles.scss b/src/plugins/d3/renderer/hooks/useShapes/styles.scss deleted file mode 100644 index 7a465834..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/styles.scss +++ /dev/null @@ -1,48 +0,0 @@ -.chartkit-d3-scatter { - &__point { - stroke-width: 1px; - } -} - -.chartkit-d3-pie { - &__segment { - stroke: var(--g-color-base-background); - } - - &__label { - fill: var(--g-color-text-complementary); - font-size: 11px; - font-weight: bold; - alignment-baseline: before-edge; - } -} - -.chartkit-d3-bar-x { - &__label { - fill: var(--g-color-text-complementary); - user-select: none; - } -} - -.chartkit-d3-bar-y { - &__label { - fill: var(--g-color-text-complementary); - user-select: none; - alignment-baseline: after-edge; - } -} - -.chartkit-d3-treemap { - &__label { - fill: var(--g-color-text-complementary); - alignment-baseline: text-before-edge; - user-select: none; - pointer-events: none; - } -} - -.chartkit-d3-waterfall { - &__connector { - stroke: var(--g-color-line-generic-active); - } -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/treemap/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/treemap/index.tsx deleted file mode 100644 index a36d7e63..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/treemap/index.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React from 'react'; - -import {color, select} from 'd3'; -import type {BaseType, Dispatch, HierarchyRectangularNode} from 'd3'; -import get from 'lodash/get'; - -import type {TooltipDataChunkTreemap, TreemapSeriesData} from '../../../../../../types'; -import {block} from '../../../../../../utils/cn'; -import {setEllipsisForOverflowTexts} from '../../../utils'; -import {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; - -import type {PreparedTreemapData, TreemapLabelData} from './types'; - -const b = block('d3-treemap'); - -type ShapeProps = { - dispatcher: Dispatch; - preparedData: PreparedTreemapData; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const TreemapSeriesShape = (props: ShapeProps) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = props; - const ref = React.useRef(null); - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - svgElement.selectAll('*').remove(); - const {labelData, leaves, series} = preparedData; - const leaf = svgElement - .selectAll('g') - .data(leaves) - .join('g') - .attr('transform', (d) => `translate(${d.x0},${d.y0})`) - .attr('cursor', series.cursor); - const rectSelection = leaf - .append('rect') - .attr('id', (d) => d.id || d.name) - .attr('fill', (d) => { - if (d.data.color) { - return d.data.color; - } - - const levelOptions = series.levels?.find((l) => l.index === d.depth); - return levelOptions?.color || series.color; - }) - .attr('width', (d) => d.x1 - d.x0) - .attr('height', (d) => d.y1 - d.y0); - const labelSelection = svgElement - .selectAll('tspan') - .data(labelData) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .style('font-size', () => series.dataLabels.style.fontSize) - .style('font-weight', () => series.dataLabels.style?.fontWeight || null) - .style('fill', () => series.dataLabels.style?.fontColor || null) - .call(setEllipsisForOverflowTexts, (d) => d.width); - - const eventName = `hover-shape.treemap`; - const hoverOptions = get(seriesOptions, 'treemap.states.hover'); - const inactiveOptions = get(seriesOptions, 'treemap.states.inactive'); - - dispatcher.on(eventName, (data?: TooltipDataChunkTreemap[]) => { - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - const hoveredData = data?.[0]?.data; - rectSelection.datum((d, index, list) => { - const currentRect = select>( - list[index], - ); - const hovered = Boolean(hoverEnabled && hoveredData === d.data); - const inactive = Boolean(inactiveEnabled && hoveredData && !hovered); - currentRect - .attr('fill', (currentD) => { - const levelOptions = series.levels?.find((l) => l.index === currentD.depth); - const initialColor = levelOptions?.color || d.data.color || series.color; - if (hovered) { - return ( - color(initialColor) - ?.brighter(hoverOptions?.brightness) - .toString() || initialColor - ); - } - return initialColor; - }) - .attr('opacity', () => { - if (inactive) { - return inactiveOptions?.opacity || null; - } - return null; - }); - - return d; - }); - labelSelection.datum((d, index, list) => { - const currentLabel = select(list[index]); - const hovered = Boolean(hoverEnabled && hoveredData === d.nodeData); - const inactive = Boolean(inactiveEnabled && hoveredData && !hovered); - currentLabel.attr('opacity', () => { - if (inactive) { - return inactiveOptions?.opacity || null; - } - return null; - }); - return d; - }); - }); - - return () => { - dispatcher.on(eventName, null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/treemap/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/treemap/prepare-data.ts deleted file mode 100644 index aa31bf81..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/treemap/prepare-data.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { - stratify, - treemap, - treemapBinary, - treemapDice, - treemapSlice, - treemapSliceDice, - treemapSquarify, -} from 'd3'; -import type {HierarchyRectangularNode} from 'd3'; - -import {LayoutAlgorithm} from '../../../../../../constants'; -import type {TreemapSeriesData} from '../../../../../../types'; -import {HtmlItem} from '../../../types'; -import {getLabelsSize} from '../../../utils'; -import type {PreparedTreemapSeries} from '../../useSeries/types'; - -import type {PreparedTreemapData, TreemapLabelData} from './types'; - -const DEFAULT_PADDING = 1; - -type LabelItem = HtmlItem | TreemapLabelData; - -function getLabels(args: { - data: HierarchyRectangularNode[]; - html: boolean; - padding: number; - align: PreparedTreemapSeries['dataLabels']['align']; -}) { - const {data, html, padding, align} = args; - - return data.reduce((acc, d) => { - const texts = Array.isArray(d.data.name) ? d.data.name : [d.data.name]; - - texts.forEach((text, index) => { - const {maxHeight: lineHeight, maxWidth: labelWidth} = - getLabelsSize({labels: [text], html}) ?? {}; - const left = d.x0 + padding; - const right = d.x1 - padding; - const width = Math.max(0, right - left); - let x = left; - const y = index * lineHeight + d.y0 + padding; - - switch (align) { - case 'left': { - x = left; - break; - } - case 'center': { - x = Math.max(left, left + (width - labelWidth) / 2); - break; - } - case 'right': { - x = Math.max(left, right - labelWidth); - break; - } - } - - const item: LabelItem = html - ? { - content: text, - x, - y, - } - : { - text, - x, - y, - width, - nodeData: d.data, - }; - - acc.push(item); - }); - - return acc; - }, []); -} - -export function prepareTreemapData(args: { - series: PreparedTreemapSeries; - width: number; - height: number; -}): PreparedTreemapData { - const {series, width, height} = args; - const dataWithRootNode = getSeriesDataWithRootNode(series); - const hierarchy = stratify() - .id((d) => { - if (d.id) { - return d.id; - } - - return Array.isArray(d.name) ? d.name.join() : d.name; - }) - .parentId((d) => d.parentId)(dataWithRootNode) - .sum((d) => d.value || 0); - const treemapInstance = treemap(); - - switch (series.layoutAlgorithm) { - case LayoutAlgorithm.Binary: { - treemapInstance.tile(treemapBinary); - break; - } - case LayoutAlgorithm.Dice: { - treemapInstance.tile(treemapDice); - break; - } - case LayoutAlgorithm.Slice: { - treemapInstance.tile(treemapSlice); - break; - } - case LayoutAlgorithm.SliceDice: { - treemapInstance.tile(treemapSliceDice); - break; - } - case LayoutAlgorithm.Squarify: { - treemapInstance.tile(treemapSquarify); - break; - } - } - - const root = treemapInstance.size([width, height]).paddingInner((d) => { - const levelOptions = series.levels?.find((l) => l.index === d.depth + 1); - return levelOptions?.padding ?? DEFAULT_PADDING; - })(hierarchy); - const leaves = root.leaves(); - let labelData: TreemapLabelData[] = []; - const htmlElements: HtmlItem[] = []; - - if (series.dataLabels?.enabled) { - const {html, padding, align} = series.dataLabels; - const labels = getLabels({html, padding, align, data: leaves}); - if (html) { - htmlElements.push(...(labels as HtmlItem[])); - } else { - labelData = labels as TreemapLabelData[]; - } - } - - return {labelData, leaves, series, htmlElements}; -} - -function getSeriesDataWithRootNode(series: PreparedTreemapSeries) { - return series.data.reduce( - (acc, d) => { - const dataChunk = Object.assign({}, d); - - if (!dataChunk.parentId) { - dataChunk.parentId = series.id; - } - - acc.push(dataChunk); - - return acc; - }, - [{name: series.name, id: series.id}], - ); -} diff --git a/src/plugins/d3/renderer/hooks/useShapes/treemap/types.ts b/src/plugins/d3/renderer/hooks/useShapes/treemap/types.ts deleted file mode 100644 index 180a69f2..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/treemap/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type {HierarchyRectangularNode} from 'd3'; - -import type {TreemapSeriesData} from '../../../../../../types'; -import {HtmlItem} from '../../../types'; -import type {PreparedTreemapSeries} from '../../useSeries/types'; - -export type TreemapLabelData = { - text: string; - x: number; - y: number; - width: number; - nodeData: TreemapSeriesData; -}; - -export type PreparedTreemapData = { - labelData: TreemapLabelData[]; - leaves: HierarchyRectangularNode>[]; - series: PreparedTreemapSeries; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/utils.ts b/src/plugins/d3/renderer/hooks/useShapes/utils.ts deleted file mode 100644 index f9409bfe..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/utils.ts +++ /dev/null @@ -1,87 +0,0 @@ -import type {BaseType, ScaleBand, ScaleLinear, ScaleTime} from 'd3'; -import {select} from 'd3'; -import get from 'lodash/get'; - -import {DashStyle} from '../../../../../constants'; -import type {BasicInactiveState} from '../../../../../types'; -import {getDataCategoryValue} from '../../utils'; -import type {ChartScale} from '../useAxisScales'; -import type {PreparedAxis} from '../useChartOptions/types'; - -import type {PreparedLineData} from './line/types'; - -export function getXValue(args: { - point: {x?: number | string}; - xAxis: PreparedAxis; - xScale: ChartScale; -}) { - const {point, xAxis, xScale} = args; - - if (xAxis.type === 'category') { - const xBandScale = xScale as ScaleBand; - const categories = get(xAxis, 'categories', [] as string[]); - const dataCategory = getDataCategoryValue({axisDirection: 'x', categories, data: point}); - return (xBandScale(dataCategory) || 0) + xBandScale.step() / 2; - } - - const xLinearScale = xScale as ScaleLinear | ScaleTime; - return xLinearScale(point.x as number); -} - -export function getYValue(args: { - point: {y?: number | string}; - yAxis: PreparedAxis; - yScale: ChartScale; -}) { - const {point, yAxis, yScale} = args; - - if (yAxis.type === 'category') { - const yBandScale = yScale as ScaleBand; - const categories = get(yAxis, 'categories', [] as string[]); - const dataCategory = getDataCategoryValue({axisDirection: 'y', categories, data: point}); - return (yBandScale(dataCategory) || 0) + yBandScale.step() / 2; - } - - const yLinearScale = yScale as ScaleLinear | ScaleTime; - return yLinearScale(point.y as number); -} - -export const shapeKey = (d: unknown) => (d as PreparedLineData).id || -1; - -export function setActiveState(args: { - element: BaseType; - datum: T; - state: BasicInactiveState | undefined; - active: boolean; -}) { - const {element, datum, state, active} = args; - const elementSelection = select(element); - - if (datum.active !== active) { - datum.active = active; - const opacity = datum.active ? null : state?.opacity; - elementSelection.attr('opacity', opacity || null); - } - - return datum; -} - -export const getLineDashArray = (dashStyle: DashStyle, strokeWidth = 2) => { - const value = dashStyle.toLowerCase(); - - const arrayValue = value - .replace('shortdashdotdot', '3,1,1,1,1,1,') - .replace('shortdashdot', '3,1,1,1') - .replace('shortdot', '1,1,') - .replace('shortdash', '3,1,') - .replace('longdash', '8,3,') - .replace(/dot/g, '1,3,') - .replace('dash', '4,3,') - .replace(/,$/, '') - .split(',') - .map((part) => { - return `${parseInt(part, 10) * strokeWidth}`; - }); - - return arrayValue.join(',').replace(/NaN/g, 'none'); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/waterfall/index.tsx b/src/plugins/d3/renderer/hooks/useShapes/waterfall/index.tsx deleted file mode 100644 index e8a071b1..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/waterfall/index.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import React from 'react'; - -import {color, line as lineGenerator, select} from 'd3'; -import type {Dispatch} from 'd3'; -import get from 'lodash/get'; - -import {DashStyle} from '../../../../../../constants'; -import {block} from '../../../../../../utils/cn'; -import type {LabelData} from '../../../types'; -import {filterOverlappingLabels, getWaterfallPointColor} from '../../../utils'; -import type {PreparedSeriesOptions} from '../../useSeries/types'; -import {HtmlLayer} from '../HtmlLayer'; -import {getLineDashArray} from '../utils'; - -import type {PreparedWaterfallData} from './types'; - -export {prepareWaterfallData} from './prepare-data'; -export * from './types'; - -const b = block('d3-waterfall'); - -type Args = { - dispatcher: Dispatch; - preparedData: PreparedWaterfallData[]; - seriesOptions: PreparedSeriesOptions; - htmlLayout: HTMLElement | null; -}; - -export const WaterfallSeriesShapes = (args: Args) => { - const {dispatcher, preparedData, seriesOptions, htmlLayout} = args; - - const ref = React.useRef(null); - const connectorSelector = `.${b('connector')}`; - - React.useEffect(() => { - if (!ref.current) { - return () => {}; - } - - const svgElement = select(ref.current); - const hoverOptions = get(seriesOptions, 'waterfall.states.hover'); - const inactiveOptions = get(seriesOptions, 'waterfall.states.inactive'); - svgElement.selectAll('*').remove(); - const rectSelection = svgElement - .selectAll('allRects') - .data(preparedData) - .join('rect') - .attr('class', b('segment')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('height', (d) => d.height) - .attr('width', (d) => d.width) - .attr('fill', (d) => getWaterfallPointColor(d.data, d.series)) - .attr('opacity', (d) => d.opacity) - .attr('cursor', (d) => d.series.cursor); - - let dataLabels = preparedData.map((d) => d.label).filter(Boolean) as LabelData[]; - if (!preparedData[0]?.series.dataLabels.allowOverlap) { - dataLabels = filterOverlappingLabels(dataLabels); - } - - const labelSelection = svgElement - .selectAll('text') - .data(dataLabels) - .join('text') - .text((d) => d.text) - .attr('class', b('label')) - .attr('x', (d) => d.x) - .attr('y', (d) => d.y) - .attr('text-anchor', (d) => d.textAnchor) - .style('font-size', (d) => d.style.fontSize) - .style('font-weight', (d) => d.style.fontWeight || null) - .style('fill', (d) => d.style.fontColor || null); - - // Add the connector line between bars - svgElement - .selectAll(connectorSelector) - .data(preparedData) - .join('path') - .attr('class', b('connector')) - .attr('d', (d, index) => { - const line = lineGenerator(); - - const prev = preparedData[index - 1]; - if (!prev) { - return null; - } - - const points: [number, number][] = []; - if (Number(prev.data.y) > 0) { - points.push([prev.x, prev.y]); - } else { - points.push([prev.x, prev.y + prev.height]); - } - - if (Number(d.data.y) > 0 && !d.data.total) { - points.push([d.x + d.width, d.y + d.height]); - } else { - points.push([d.x + d.width, d.y]); - } - - return line(points); - }) - .attr('stroke-width', 1) - .attr('stroke-dasharray', () => getLineDashArray(DashStyle.Dash, 1)); - - dispatcher.on('hover-shape.waterfall', (data?: PreparedWaterfallData[]) => { - const hoverEnabled = hoverOptions?.enabled; - const inactiveEnabled = inactiveOptions?.enabled; - - if (!data) { - if (hoverEnabled) { - rectSelection.attr('fill', (d) => getWaterfallPointColor(d.data, d.series)); - } - - if (inactiveEnabled) { - rectSelection.attr('opacity', null); - labelSelection.attr('opacity', null); - } - - return; - } - - if (hoverEnabled) { - const hoveredValues = data.map((d) => d.data.x); - rectSelection.attr('fill', (d) => { - const fillColor = getWaterfallPointColor(d.data, d.series); - - if (hoveredValues.includes(d.data.x)) { - const brightness = hoverOptions?.brightness; - return color(fillColor)?.brighter(brightness).toString() || fillColor; - } - - return fillColor; - }); - } - - if (inactiveEnabled) { - const hoveredSeries = data.map((d) => d.series.id); - rectSelection.attr('opacity', (d) => { - return hoveredSeries.includes(d.series.id) - ? null - : inactiveOptions?.opacity || null; - }); - labelSelection.attr('opacity', (d) => { - return hoveredSeries.includes(d.series.id) - ? null - : inactiveOptions?.opacity || null; - }); - } - }); - - return () => { - dispatcher.on('hover-shape.waterfall', null); - }; - }, [dispatcher, preparedData, seriesOptions]); - - return ( - - - - - ); -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/waterfall/prepare-data.ts b/src/plugins/d3/renderer/hooks/useShapes/waterfall/prepare-data.ts deleted file mode 100644 index 2643dcc6..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/waterfall/prepare-data.ts +++ /dev/null @@ -1,181 +0,0 @@ -import type {ScaleBand, ScaleLinear, ScaleTime} from 'd3'; -import get from 'lodash/get'; -import sortBy from 'lodash/sortBy'; - -import type {WaterfallSeriesData} from '../../../../../../types'; -import type {LabelData} from '../../../types'; -import {getLabelsSize} from '../../../utils'; -import type {ChartScale} from '../../useAxisScales'; -import type {PreparedAxis} from '../../useChartOptions/types'; -import type {PreparedSeriesOptions, PreparedWaterfallSeries} from '../../useSeries/types'; -import {MIN_BAR_GAP, MIN_BAR_WIDTH} from '../constants'; -import {getXValue, getYValue} from '../utils'; - -import type {PreparedWaterfallData} from './types'; - -function getLabelData(d: PreparedWaterfallData, plotHeight: number): LabelData | undefined { - if (!d.series.dataLabels.enabled) { - return undefined; - } - - const text = String(d.data.label || d.subTotal); - const style = d.series.dataLabels.style; - const {maxHeight: height, maxWidth: width} = getLabelsSize({labels: [text], style}); - - let y: number; - if (Number(d.data.y) > 0 || d.data.total) { - y = Math.max(height, d.y - d.series.dataLabels.padding); - } else { - y = Math.min( - plotHeight - d.series.dataLabels.padding, - d.y + d.height + d.series.dataLabels.padding + height, - ); - } - - return { - text, - x: d.x + d.width / 2, - y, - style, - size: {width, height}, - textAnchor: 'middle', - series: d.series, - }; -} - -function getBandWidth(args: { - series: PreparedWaterfallSeries[]; - xAxis: PreparedAxis; - xScale: ChartScale; -}) { - const {series, xAxis, xScale} = args; - - if (xAxis.type === 'category') { - const xBandScale = xScale as ScaleBand; - return xBandScale.bandwidth(); - } - - const xLinearScale = xScale as ScaleLinear | ScaleTime; - const xValues = series.reduce((acc, s) => { - s.data.forEach((dataItem) => acc.push(Number(dataItem.x))); - return acc; - }, []); - - let bandWidth = Infinity; - xValues.sort().forEach((xValue, index) => { - if (index > 0 && xValue !== xValues[index - 1]) { - const dist = xLinearScale(xValue) - xLinearScale(xValues[index - 1]); - if (dist < bandWidth) { - bandWidth = dist; - } - } - }); - - return bandWidth; -} - -type DataItem = {data: WaterfallSeriesData; series: PreparedWaterfallSeries}; - -export const prepareWaterfallData = (args: { - series: PreparedWaterfallSeries[]; - seriesOptions: PreparedSeriesOptions; - xAxis: PreparedAxis; - xScale: ChartScale; - yAxis: PreparedAxis[]; - yScale: ChartScale[]; -}): PreparedWaterfallData[] => { - const { - series, - seriesOptions, - xAxis, - xScale, - yAxis: [yAxis], - yScale: [yScale], - } = args; - const yLinearScale = yScale as ScaleLinear; - const plotHeight = yLinearScale(yLinearScale.domain()[0]); - const barMaxWidth = get(seriesOptions, 'waterfall.barMaxWidth'); - const barPadding = get(seriesOptions, 'waterfall.barPadding'); - - const flattenData = series.reduce((acc, s) => { - acc.push(...s.data.map((d) => ({data: d, series: s}))); - return acc; - }, []); - const data: DataItem[] = sortBy(flattenData, (d) => d.data.x); - - const bandWidth = getBandWidth({ - series, - xAxis, - xScale, - }); - const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP); - const rectWidth = Math.max(MIN_BAR_WIDTH, Math.min(bandWidth - rectGap, barMaxWidth)); - const yZero = getYValue({ - point: {y: 0}, - yScale, - yAxis, - }); - - let totalValue = 0; - const result: PreparedWaterfallData[] = []; - data.forEach((item, _index) => { - if (typeof item.data.y !== 'number' && !item.data.total) { - return; - } - - if (!item.data.total) { - totalValue += Number(item.data.y); - } - - const prevPoint = result[result.length - 1]; - const xCenter = getXValue({point: item.data, xAxis, xScale}); - const x = xCenter - rectWidth / 2; - const yValue = Number(item.data.total ? totalValue : item.data.y); - const height = - yZero - - getYValue({ - point: {y: Math.abs(yValue)}, - yScale, - yAxis, - }); - - let y; - if (!prevPoint || item.data.total) { - y = getYValue({ - point: { - y: yValue > 0 ? yValue : 0, - }, - yScale, - yAxis, - }); - } else if (Number(prevPoint.data.y) < 0) { - if (Number(item.data.y) > 0) { - y = prevPoint.y + prevPoint.height - height; - } else { - y = prevPoint.y + prevPoint.height; - } - } else if (Number(item.data.y) < 0) { - y = prevPoint.y; - } else { - y = prevPoint.y - height; - } - - const preparedData: PreparedWaterfallData = { - x, - y, - width: rectWidth, - height, - opacity: get(item.data, 'opacity', null), - data: item.data, - series: item.series, - subTotal: totalValue, - htmlElements: [], - }; - - preparedData.label = getLabelData(preparedData, plotHeight); - - result.push(preparedData); - }); - - return result; -}; diff --git a/src/plugins/d3/renderer/hooks/useShapes/waterfall/types.ts b/src/plugins/d3/renderer/hooks/useShapes/waterfall/types.ts deleted file mode 100644 index 0f38e7bb..00000000 --- a/src/plugins/d3/renderer/hooks/useShapes/waterfall/types.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {WaterfallSeriesData} from '../../../../../../types'; -import {HtmlItem, LabelData} from '../../../types'; -import {PreparedWaterfallSeries} from '../../useSeries/types'; - -export type PreparedWaterfallData = { - x: number; - y: number; - width: number; - height: number; - opacity: number | null; - series: PreparedWaterfallSeries; - data: WaterfallSeriesData; - label?: LabelData; - subTotal: number; - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/hooks/useSplit/index.ts b/src/plugins/d3/renderer/hooks/useSplit/index.ts deleted file mode 100644 index 3a0cc0f4..00000000 --- a/src/plugins/d3/renderer/hooks/useSplit/index.ts +++ /dev/null @@ -1,85 +0,0 @@ -import get from 'lodash/get'; - -import type {BaseTextStyle, ChartKitWidgetSplit, SplitPlotOptions} from '../../../../../types'; -import {calculateNumericProperty, getHorisontalSvgTextHeight} from '../../utils'; - -import type {PreparedPlot, PreparedPlotTitle, PreparedSplit} from './types'; - -type UseSplitArgs = { - split?: ChartKitWidgetSplit; - boundsHeight: number; - chartWidth: number; -}; - -const DEFAULT_TITLE_FONT_SIZE = '15px'; -const TITLE_TOP_BOTTOM_PADDING = 8; - -function preparePlotTitle(args: { - title: SplitPlotOptions['title']; - plotIndex: number; - plotHeight: number; - chartWidth: number; - gap: number; -}): PreparedPlotTitle { - const {title, plotIndex, plotHeight, chartWidth, gap} = args; - const titleText = title?.text || ''; - const titleStyle: BaseTextStyle = { - fontSize: get(title, 'style.fontSize', DEFAULT_TITLE_FONT_SIZE), - fontWeight: get(title, 'style.fontWeight'), - }; - const titleHeight = titleText - ? getHorisontalSvgTextHeight({text: titleText, style: titleStyle}) + - TITLE_TOP_BOTTOM_PADDING * 2 - : 0; - const top = plotIndex * (plotHeight + gap); - - return { - text: titleText, - x: chartWidth / 2, - y: top + titleHeight / 2, - style: titleStyle, - height: titleHeight, - }; -} - -export function getPlotHeight(args: { - split: ChartKitWidgetSplit | undefined; - boundsHeight: number; - gap: number; -}) { - const {split, boundsHeight, gap} = args; - const plots = split?.plots || []; - - if (plots.length > 1) { - return (boundsHeight - gap * (plots.length - 1)) / plots.length; - } - - return boundsHeight; -} - -export const useSplit = (args: UseSplitArgs): PreparedSplit => { - const {split, boundsHeight, chartWidth} = args; - const splitGap = calculateNumericProperty({value: split?.gap, base: boundsHeight}) ?? 0; - const plotHeight = getPlotHeight({split: split, boundsHeight, gap: splitGap}); - - const plots = split?.plots || []; - return { - plots: plots.map((p, index) => { - const title = preparePlotTitle({ - title: p.title, - plotIndex: index, - gap: splitGap, - plotHeight, - chartWidth, - }); - const top = index * (plotHeight + splitGap); - - return { - top: top + title.height, - height: plotHeight - title.height, - title, - }; - }), - gap: splitGap, - }; -}; diff --git a/src/plugins/d3/renderer/hooks/useSplit/types.ts b/src/plugins/d3/renderer/hooks/useSplit/types.ts deleted file mode 100644 index 9ebf56a2..00000000 --- a/src/plugins/d3/renderer/hooks/useSplit/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type {BaseTextStyle} from '../../../../../types'; - -export type PreparedSplit = { - plots: PreparedPlot[]; - gap: number; -}; - -export type PreparedPlot = { - title: PreparedPlotTitle; - top: number; - height: number; -}; - -export type PreparedPlotTitle = { - x: number; - y: number; - text: string; - style?: Partial; - height: number; -}; diff --git a/src/plugins/d3/renderer/hooks/useTooltip/index.ts b/src/plugins/d3/renderer/hooks/useTooltip/index.ts deleted file mode 100644 index 9f06f556..00000000 --- a/src/plugins/d3/renderer/hooks/useTooltip/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; - -import type {Dispatch} from 'd3'; - -import type {TooltipDataChunk} from '../../../../../types/widget-data'; -import {PreparedTooltip} from '../useChartOptions/types'; - -import type {PointerPosition} from './types'; - -type Args = { - dispatcher: Dispatch; - tooltip: PreparedTooltip; -}; - -type TooltipState = { - hovered?: TooltipDataChunk[]; - pointerPosition?: PointerPosition; -}; - -export const useTooltip = ({dispatcher, tooltip}: Args) => { - const [{hovered, pointerPosition}, setTooltipState] = React.useState({}); - - React.useEffect(() => { - if (tooltip?.enabled) { - dispatcher.on( - 'hover-shape.tooltip', - (nextHovered?: TooltipDataChunk[], nextPointerPosition?: PointerPosition) => { - setTooltipState({hovered: nextHovered, pointerPosition: nextPointerPosition}); - }, - ); - } - - return () => { - if (tooltip?.enabled) { - dispatcher.on('hover-shape.tooltip', null); - } - }; - }, [dispatcher, tooltip]); - - return {hovered, pointerPosition}; -}; diff --git a/src/plugins/d3/renderer/hooks/useTooltip/types.ts b/src/plugins/d3/renderer/hooks/useTooltip/types.ts deleted file mode 100644 index ae2a5065..00000000 --- a/src/plugins/d3/renderer/hooks/useTooltip/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type PointerPosition = [number, number]; diff --git a/src/plugins/d3/renderer/types/index.ts b/src/plugins/d3/renderer/types/index.ts deleted file mode 100644 index 6fc5f49f..00000000 --- a/src/plugins/d3/renderer/types/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {BaseTextStyle} from '../../../../types'; - -export type LabelData = { - text: string; - x: number; - y: number; - style: BaseTextStyle; - size: {width: number; height: number}; - textAnchor: 'start' | 'end' | 'middle'; - series: {id: string}; - active?: boolean; -}; - -export type HtmlItem = { - x: number; - y: number; - content: string; -}; - -export type ShapeDataWithHtmlItems = { - htmlElements: HtmlItem[]; -}; diff --git a/src/plugins/d3/renderer/utils/__tests__/labels.test.ts b/src/plugins/d3/renderer/utils/__tests__/labels.test.ts deleted file mode 100644 index e77ae54c..00000000 --- a/src/plugins/d3/renderer/utils/__tests__/labels.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -import type {LabelData} from '../../types'; -import {filterOverlappingLabels} from '../labels'; - -describe('filterOverlappingLabels', () => { - const label1 = { - text: 'A', - x: 10, - y: 5, - size: { - width: 20, - height: 15, - }, - textAnchor: 'middle', - }; - - it('overlap by X and Y -> remove overlapping', () => { - const label2 = { - text: 'B', - x: 22, - y: 7, - size: { - width: 10, - height: 15, - }, - textAnchor: 'middle', - }; - const labels = [label1, label2]; - expect(filterOverlappingLabels(labels as LabelData[])).toEqual([label1]); - }); - - it('overlap only by X -> do nothing ', () => { - const label2 = { - text: 'B', - x: 22, - y: 100, - size: { - width: 10, - height: 15, - }, - textAnchor: 'middle', - }; - const labels = [label1, label2]; - expect(filterOverlappingLabels(labels as LabelData[])).toEqual([label1, label2]); - }); - - it('overlap only by Y -> do nothing ', () => { - const label2 = { - text: 'B', - x: 200, - y: 7, - size: { - width: 10, - height: 15, - }, - textAnchor: 'middle', - }; - const labels = [label1, label2]; - expect(filterOverlappingLabels(labels as LabelData[])).toEqual([label1, label2]); - }); -}); diff --git a/src/plugins/d3/renderer/utils/axis-generators/bottom.ts b/src/plugins/d3/renderer/utils/axis-generators/bottom.ts deleted file mode 100644 index e8a793ef..00000000 --- a/src/plugins/d3/renderer/utils/axis-generators/bottom.ts +++ /dev/null @@ -1,195 +0,0 @@ -import type {AxisDomain, AxisScale, Selection} from 'd3'; -import {path, select} from 'd3'; - -import {BaseTextStyle} from '../../../../../types'; -import {getXAxisItems, getXAxisOffset, getXTickPosition} from '../axis'; -import {calculateCos, calculateSin} from '../math'; -import {getLabelsSize, setEllipsisForOverflowText} from '../text'; - -type AxisBottomArgs = { - scale: AxisScale; - ticks: { - count?: number; - maxTickCount?: number; - labelFormat?: (value: any) => string; - labelsPaddings?: number; - labelsMargin?: number; - labelsStyle?: BaseTextStyle; - labelsMaxWidth?: number; - labelsLineHeight: number; - items?: [number, number][]; - rotation?: number; - tickColor?: string; - }; - domain: { - size: number; - color?: string; - }; -}; - -function addDomain( - selection: Selection, - options: { - size: number; - color?: string; - }, -) { - const {size, color} = options; - - const domainPath = selection - .selectAll('.domain') - .data([null]) - .enter() - .insert('path', '.tick') - .attr('class', 'domain') - .attr('d', `M0,0V0H${size}`); - - if (color) { - domainPath.style('stroke', color); - } -} - -export function axisBottom(args: AxisBottomArgs) { - const { - scale, - ticks: { - labelFormat = (value: unknown) => String(value), - labelsPaddings = 0, - labelsMargin = 0, - labelsMaxWidth = Infinity, - labelsStyle, - labelsLineHeight, - items: tickItems, - count: ticksCount, - maxTickCount, - rotation = 0, - tickColor, - }, - domain, - } = args; - const offset = getXAxisOffset(); - const position = getXTickPosition({scale, offset}); - const values = getXAxisItems({scale, count: ticksCount, maxCount: maxTickCount}); - const labelHeight = getLabelsSize({ - labels: values, - style: labelsStyle, - }).maxHeight; - - return function (selection: Selection) { - const rect = selection.node()?.getBoundingClientRect(); - const x = rect?.x || 0; - - const right = x + domain.size; - const top = -(tickItems?.[0]?.[0] ?? 0); - - let transform = `translate(0, ${labelHeight + labelsMargin - top}px)`; - if (rotation) { - const labelsOffsetTop = labelHeight * calculateCos(rotation) + labelsMargin - top; - let labelsOffsetLeft = calculateSin(rotation) * labelHeight; - if (Math.abs(rotation) % 360 === 90) { - labelsOffsetLeft += ((rotation > 0 ? -1 : 1) * labelHeight) / 2; - } - transform = `translate(${-labelsOffsetLeft}px, ${labelsOffsetTop}px) rotate(${rotation}deg)`; - } - - const tickPath = path(); - tickItems?.forEach(([start, end]) => { - tickPath.moveTo(0, start); - tickPath.lineTo(0, end); - }); - - selection - .selectAll('.tick') - .data(values) - .order() - .join((el) => { - const tick = el.append('g').attr('class', 'tick'); - tick.append('path') - .attr('d', tickPath.toString()) - .attr('stroke', tickColor ?? 'currentColor'); - tick.append('text') - .text(labelFormat) - .attr('fill', 'currentColor') - .attr('text-anchor', () => { - if (rotation) { - return rotation > 0 ? 'start' : 'end'; - } - return 'middle'; - }) - .style('transform', transform) - .style('alignment-baseline', 'after-edge'); - - return tick; - }) - .attr('transform', function (d) { - return `translate(${position(d as AxisDomain) + offset}, ${top})`; - }); - - // Remove tick that has the same x coordinate like domain - selection - .select('.tick') - .filter((d) => { - return position(d as AxisDomain) === 0; - }) - .select('line') - .remove(); - - const labels = selection.selectAll('.tick text'); - - // FIXME: handle rotated overlapping labels (with a smarter approach) - if (rotation) { - const maxWidth = - labelsMaxWidth * calculateCos(rotation) + labelsLineHeight * calculateSin(rotation); - labels.each(function () { - setEllipsisForOverflowText(select(this), maxWidth); - }); - } else { - // remove overlapping labels - let elementX = 0; - selection - .selectAll('.tick') - .filter(function () { - const node = this as unknown as Element; - const r = node.getBoundingClientRect(); - - if (r.left < elementX) { - return true; - } - elementX = r.right + labelsPaddings; - return false; - }) - .remove(); - - // add an ellipsis to the labels that go beyond the boundaries of the chart - labels.each(function (_d, i, nodes) { - if (i === nodes.length - 1) { - const currentElement = this as SVGTextElement; - const prevElement = nodes[i - 1] as SVGTextElement; - const text = select(currentElement); - - const currentElementPosition = currentElement.getBoundingClientRect(); - const prevElementPosition = prevElement?.getBoundingClientRect(); - - const lackingSpace = Math.max(0, currentElementPosition.right - right); - if (lackingSpace) { - const remainSpace = - right - (prevElementPosition?.right || 0) - labelsPaddings; - - const translateX = currentElementPosition.width / 2 - lackingSpace; - text.attr('text-anchor', 'end').attr( - 'transform', - `translate(${translateX},0)`, - ); - - setEllipsisForOverflowText(text, remainSpace); - } - } - }); - } - - const {size: domainSize, color: domainColor} = domain; - selection - .call(addDomain, {size: domainSize, color: domainColor}) - .style('font-size', labelsStyle?.fontSize || ''); - }; -} diff --git a/src/plugins/d3/renderer/utils/axis-generators/index.ts b/src/plugins/d3/renderer/utils/axis-generators/index.ts deleted file mode 100644 index 2321bbf8..00000000 --- a/src/plugins/d3/renderer/utils/axis-generators/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './bottom'; diff --git a/src/plugins/d3/renderer/utils/axis.ts b/src/plugins/d3/renderer/utils/axis.ts deleted file mode 100644 index 7371358e..00000000 --- a/src/plugins/d3/renderer/utils/axis.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type {AxisDomain, AxisScale, ScaleBand} from 'd3'; - -import type {PreparedAxis, PreparedSplit} from '../hooks'; - -import type {TextRow} from './text'; -import {wrapText} from './text'; - -export function getTicksCount({axis, range}: {axis: PreparedAxis; range: number}) { - let ticksCount: number | undefined; - - if (axis.ticks.pixelInterval) { - ticksCount = Math.ceil(range / axis.ticks.pixelInterval); - } - - return ticksCount; -} - -export function isBandScale(scale: AxisScale): scale is ScaleBand { - return 'bandwidth' in scale && typeof scale.bandwidth === 'function'; -} - -export function getScaleTicks(scale: AxisScale, ticksCount?: number) { - return 'ticks' in scale && typeof scale.ticks === 'function' - ? scale.ticks(ticksCount) - : scale.domain(); -} - -export function getXAxisOffset() { - return typeof window !== 'undefined' && window.devicePixelRatio > 1 ? 0 : 0.5; -} - -function number(scale: AxisScale) { - return (d: AxisDomain) => Number(scale(d)); -} - -function center(scale: ScaleBand, offset: number) { - offset = Math.max(0, scale.bandwidth() - offset * 2) / 2; - if (scale.round()) { - offset = Math.round(offset); - } - return (d: AxisDomain) => Number(scale(d)) + offset; -} - -export function getXTickPosition({scale, offset}: {scale: AxisScale; offset: number}) { - return isBandScale(scale) ? center(scale.copy(), offset) : number(scale.copy()); -} - -export function getXAxisItems({ - scale, - count, - maxCount, -}: { - scale: AxisScale; - count?: number; - maxCount?: number; -}) { - let values = getScaleTicks(scale, count); - - if (maxCount && values.length > maxCount) { - const step = Math.ceil(values.length / maxCount); - values = values.filter((_: AxisDomain, i: number) => i % step === 0); - } - - return values; -} - -export function getMaxTickCount({axis, width}: {axis: PreparedAxis; width: number}) { - const minTickWidth = parseInt(axis.labels.style.fontSize) + axis.labels.padding; - return Math.floor(width / minTickWidth); -} - -export function getAxisHeight(args: {split: PreparedSplit; boundsHeight: number}) { - const {split, boundsHeight} = args; - - if (split.plots.length > 1) { - return split.plots[0].height; - } - - return boundsHeight; -} - -export function getAxisTitleRows(args: {axis: PreparedAxis; textMaxWidth: number}) { - const {axis, textMaxWidth} = args; - if (axis.title.maxRowCount < 1) { - return []; - } - - const textRows = wrapText({ - text: axis.title.text, - style: axis.title.style, - width: textMaxWidth, - }); - - return textRows.reduce((acc, row, index) => { - if (index < axis.title.maxRowCount) { - acc.push(row); - } else { - acc[axis.title.maxRowCount - 1].text += row.text; - } - return acc; - }, []); -} diff --git a/src/plugins/d3/renderer/utils/color.ts b/src/plugins/d3/renderer/utils/color.ts deleted file mode 100644 index c4d59f43..00000000 --- a/src/plugins/d3/renderer/utils/color.ts +++ /dev/null @@ -1,55 +0,0 @@ -import {range, scaleLinear} from 'd3'; - -import {ChartKitWidgetData} from '../../../../types'; - -export function getDomainForContinuousColorScale(args: { - series: ChartKitWidgetData['series']['data']; -}): number[] { - const {series} = args; - const values = series.reduce((acc, s) => { - switch (s.type) { - case 'pie': { - acc.push(...s.data.map((d) => d.value)); - break; - } - case 'bar-y': { - acc.push(...s.data.map((d) => Number(d.x))); - break; - } - case 'scatter': - case 'bar-x': - case 'waterfall': - case 'line': - case 'area': { - acc.push(...s.data.map((d) => Number(d.y))); - break; - } - default: { - throw Error( - `The method for calculation a domain for a continuous color scale for the "${s.type}" series is not defined`, - ); - } - } - - return acc; - }, []); - - return [Math.min(...values), Math.max(...values)]; -} - -export function getDefaultColorStops(size: number) { - return range(size).map((d) => d / size); -} - -export function getContinuesColorFn(args: {values: number[]; colors: string[]; stops?: number[]}) { - const {values, colors, stops: customStops} = args; - const min = Math.min(...values); - const max = Math.max(...values); - const stops = customStops ?? getDefaultColorStops(colors.length); - const color = scaleLinear(stops, colors); - - return (value: number) => { - const colorValue = (value - min) / (max - min); - return color(colorValue); - }; -} diff --git a/src/plugins/d3/renderer/utils/get-closest-data.ts b/src/plugins/d3/renderer/utils/get-closest-data.ts deleted file mode 100644 index 734c7343..00000000 --- a/src/plugins/d3/renderer/utils/get-closest-data.ts +++ /dev/null @@ -1,251 +0,0 @@ -import {Delaunay, bisector, sort} from 'd3'; -import get from 'lodash/get'; -import groupBy from 'lodash/groupBy'; - -import type { - AreaSeries, - BarXSeries, - ChartKitWidgetSeries, - ChartKitWidgetSeriesData, - LineSeries, - TooltipDataChunk, - TreemapSeries, - WaterfallSeries, - WaterfallSeriesData, -} from '../../../../types'; -import type {PreparedBarXData, PreparedScatterData, ShapeData} from '../hooks'; -import type {PreparedAreaData} from '../hooks/useShapes/area/types'; -import type {PreparedBarYData} from '../hooks/useShapes/bar-y/types'; -import type {PreparedLineData} from '../hooks/useShapes/line/types'; -import type {PreparedPieData} from '../hooks/useShapes/pie/types'; -import type {PreparedTreemapData} from '../hooks/useShapes/treemap/types'; -import type {PreparedWaterfallData} from '../hooks/useShapes/waterfall'; - -type GetClosestPointsArgs = { - position: [number, number]; - shapesData: ShapeData[]; -}; - -export type ShapePoint = { - x: number; - y0: number; - y1: number; - data: ChartKitWidgetSeriesData; - series: ChartKitWidgetSeries; -}; - -function getClosestPointsByXValue(x: number, y: number, points: ShapePoint[]) { - const sorted = sort(points, (p) => p.x); - const closestXIndex = bisector((p) => p.x).center(sorted, x); - if (closestXIndex === -1) { - return []; - } - - const closestX = sorted[closestXIndex].x; - const closestPoints = sort( - points.filter((p) => p.x === closestX), - (p) => p.y0, - ); - - let closestYIndex = -1; - if (y < closestPoints[0]?.y0) { - closestYIndex = 0; - } else if (y > closestPoints[closestPoints.length - 1]?.y1) { - closestYIndex = closestPoints.length - 1; - } else { - closestYIndex = closestPoints.findIndex((p) => y > p.y0 && y < p.y1); - if (closestYIndex === -1) { - const sortedY = sort( - closestPoints.map((p, index) => ({index, y: p.y1 + (p.y0 - p.y1) / 2})), - (p) => p.y, - ); - const sortedYIndex = bisector<{y: number}, number>((p) => p.y).center(sortedY, y); - closestYIndex = sortedY[sortedYIndex]?.index ?? -1; - } - } - - return closestPoints.map((p, i) => ({ - data: p.data, - series: p.series, - closest: i === closestYIndex, - })); -} - -function getSeriesType(shapeData: ShapeData) { - return get(shapeData, 'series.type') || get(shapeData, 'point.series.type'); -} - -export function getClosestPoints(args: GetClosestPointsArgs): TooltipDataChunk[] { - const {position, shapesData} = args; - const [pointerX, pointerY] = position; - - const result: TooltipDataChunk[] = []; - const groups = groupBy(shapesData, getSeriesType); - Object.entries(groups).forEach(([seriesType, list]) => { - switch (seriesType) { - case 'bar-x': { - const points = (list as PreparedBarXData[]).map((d) => ({ - data: d.data, - series: d.series as BarXSeries, - x: d.x + d.width / 2, - y0: d.y, - y1: d.y + d.height, - })); - result.push( - ...(getClosestPointsByXValue(pointerX, pointerY, points) as TooltipDataChunk[]), - ); - - break; - } - case 'waterfall': { - const points = (list as PreparedWaterfallData[]).map((d) => ({ - data: d.data as WaterfallSeriesData, - series: d.series as WaterfallSeries, - x: d.x + d.width / 2, - y0: d.y, - y1: d.y + d.height, - })); - result.push( - ...(getClosestPointsByXValue(pointerX, pointerY, points) as TooltipDataChunk[]), - ); - - break; - } - case 'area': { - const points = (list as PreparedAreaData[]).reduce((acc, d) => { - Array.prototype.push.apply( - acc, - d.points.map((p) => ({ - data: p.data, - series: p.series as AreaSeries, - x: p.x, - y0: p.y0, - y1: p.y, - })), - ); - return acc; - }, []); - result.push( - ...(getClosestPointsByXValue(pointerX, pointerY, points) as TooltipDataChunk[]), - ); - break; - } - case 'line': { - const points = (list as PreparedLineData[]).reduce((acc, d) => { - acc.push( - ...d.points.map((p) => ({ - data: p.data, - series: p.series as LineSeries, - x: p.x, - y0: p.y, - y1: p.y, - })), - ); - return acc; - }, []); - result.push( - ...(getClosestPointsByXValue(pointerX, pointerY, points) as TooltipDataChunk[]), - ); - break; - } - case 'bar-y': { - const points = list as PreparedBarYData[]; - const sorted = sort(points, (p) => p.y); - const closestYIndex = bisector((p) => p.y).center( - sorted, - pointerY, - ); - - let closestPoints: PreparedBarYData[] = []; - let closestXIndex = -1; - if (closestYIndex !== -1) { - const closestY = sorted[closestYIndex].y; - closestPoints = sort( - points.filter((p) => p.y === closestY), - (p) => p.x, - ); - - const lastPoint = closestPoints[closestPoints.length - 1]; - if (pointerX < closestPoints[0]?.x) { - closestXIndex = 0; - } else if (lastPoint && pointerX > lastPoint.x + lastPoint.width) { - closestXIndex = closestPoints.length - 1; - } else { - closestXIndex = closestPoints.findIndex( - (p) => pointerX > p.x && pointerX < p.x + p.width, - ); - } - } - - result.push( - ...(closestPoints.map((p, i) => ({ - data: p.data, - series: p.series, - closest: i === closestXIndex, - })) as TooltipDataChunk[]), - ); - break; - } - case 'scatter': { - const points = list as PreparedScatterData[]; - const delaunayX = Delaunay.from( - points, - (d) => d.point.x, - (d) => d.point.y, - ); - const closestPoint = points[delaunayX.find(pointerX, pointerY)]; - if (closestPoint) { - result.push({ - data: closestPoint.point.data, - series: closestPoint.point.series, - closest: true, - }); - } - - break; - } - case 'pie': { - const points = (list as PreparedPieData[]).map((d) => d.segments).flat(); - const closestPoint = points.find((p) => { - const {center, radius} = p.data.pie; - const x = pointerX - center[0]; - const y = pointerY - center[1]; - let angle = Math.atan2(y, x) + 0.5 * Math.PI; - angle = angle < 0 ? Math.PI * 2 + angle : angle; - const polarRadius = Math.sqrt(x * x + y * y); - - return angle >= p.startAngle && angle <= p.endAngle && polarRadius < radius; - }); - - if (closestPoint) { - result.push({ - data: closestPoint.data.series.data, - series: closestPoint.data.series, - closest: true, - }); - } - - break; - } - case 'treemap': { - const data = list as unknown as PreparedTreemapData[]; - const closestPoint = data[0]?.leaves.find((l) => { - return ( - pointerX >= l.x0 && pointerX <= l.x1 && pointerY >= l.y0 && pointerY <= l.y1 - ); - }); - if (closestPoint) { - result.push({ - data: closestPoint.data, - series: data[0].series as TreemapSeries, - closest: true, - }); - } - - break; - } - } - }); - - return result; -} diff --git a/src/plugins/d3/renderer/utils/index.ts b/src/plugins/d3/renderer/utils/index.ts deleted file mode 100644 index 3e798267..00000000 --- a/src/plugins/d3/renderer/utils/index.ts +++ /dev/null @@ -1,299 +0,0 @@ -import {dateTime} from '@gravity-ui/date-utils'; -import {AxisDomain, group, select} from 'd3'; -import get from 'lodash/get'; -import isNil from 'lodash/isNil'; - -import type { - BaseTextStyle, - ChartKitWidgetSeries, - ChartKitWidgetSeriesData, -} from '../../../../types'; -import {formatNumber} from '../../../shared'; -import {getNumberUnitRate} from '../../../shared/format-number/format-number'; -import {DEFAULT_AXIS_LABEL_FONT_SIZE} from '../constants'; -import {PreparedAxis, PreparedWaterfallSeries, StackedSeries} from '../hooks'; -import {getSeriesStackId} from '../hooks/useSeries/utils'; - -import {getDefaultDateFormat} from './time'; - -export * from './math'; -export * from './text'; -export * from './time'; -export * from './axis'; -export * from './labels'; -export * from './legend'; -export * from './symbol'; -export * from './series'; -export * from './color'; - -const CHARTS_WITHOUT_AXIS: ChartKitWidgetSeries['type'][] = ['pie', 'treemap']; -export const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS: ChartKitWidgetSeries['type'][] = [ - 'bar-x', - 'area', - 'waterfall', -]; - -export const CHART_SERIES_WITH_VOLUME_ON_X_AXIS: ChartKitWidgetSeries['type'][] = ['bar-y']; - -export type AxisDirection = 'x' | 'y'; - -type UnknownSeries = {type: ChartKitWidgetSeries['type']; data: unknown}; - -/** - * Checks whether the series should be drawn with axes. - * - * @param series - The series object to check. - * @returns `true` if the series should be drawn with axes, `false` otherwise. - */ -export function isAxisRelatedSeries(series: UnknownSeries) { - return !CHARTS_WITHOUT_AXIS.includes(series.type); -} - -export function isSeriesWithNumericalXValues(series: UnknownSeries): series is { - type: ChartKitWidgetSeries['type']; - data: {x: number}[]; -} { - return isAxisRelatedSeries(series); -} - -export function isSeriesWithNumericalYValues(series: UnknownSeries): series is { - type: ChartKitWidgetSeries['type']; - data: {y: number}[]; -} { - return isAxisRelatedSeries(series); -} - -export function isSeriesWithCategoryValues(series: UnknownSeries): series is { - type: ChartKitWidgetSeries['type']; - data: {category: string}[]; -} { - return isAxisRelatedSeries(series); -} - -function getDomainDataForStackedSeries( - seriesList: StackedSeries[], - keyAttr: 'x' | 'y' = 'x', - valueAttr: 'x' | 'y' = 'y', -) { - const acc: number[] = []; - const stackedSeries = group(seriesList, getSeriesStackId); - Array.from(stackedSeries).forEach(([_stackId, seriesStack]) => { - const values: Record = {}; - - seriesStack.forEach((singleSeries) => { - const data = new Map(); - singleSeries.data.forEach((point) => { - const key = String(point[keyAttr]); - let value = 0; - - if (valueAttr in point && typeof point[valueAttr] === 'number') { - value = point[valueAttr] as number; - } - - if (data.has(key)) { - value = Math.max(value, data.get(key)); - } - - data.set(key, value); - }); - - Array.from(data).forEach(([key, value]) => { - values[key] = (values[key] || 0) + value; - }); - }); - - acc.push(...Object.values(values)); - }); - - return acc; -} - -export const getDomainDataXBySeries = (series: UnknownSeries[]) => { - const groupedSeries = group(series, (item) => item.type); - - return Array.from(groupedSeries).reduce((acc, [type, seriesList]) => { - switch (type) { - case 'bar-y': { - acc.push(...getDomainDataForStackedSeries(seriesList as StackedSeries[], 'y', 'x')); - break; - } - default: { - seriesList.filter(isSeriesWithNumericalXValues).forEach((s) => { - acc.push(...s.data.map((d) => d.x)); - }); - } - } - - return acc; - }, []); -}; - -export function getDefaultMaxXAxisValue(series: UnknownSeries[]) { - if (series.some((s) => s.type === 'bar-y')) { - return 0; - } - - return undefined; -} - -export const getDomainDataYBySeries = (series: UnknownSeries[]) => { - const groupedSeries = group(series, (item) => item.type); - - return Array.from(groupedSeries).reduce((acc, [type, seriesList]) => { - switch (type) { - case 'area': - case 'bar-x': { - acc.push(...getDomainDataForStackedSeries(seriesList as StackedSeries[])); - - break; - } - case 'waterfall': { - let yValue = 0; - (seriesList as PreparedWaterfallSeries[]).forEach((s) => { - s.data.forEach((d) => { - yValue += Number(d.y) || 0; - acc.push(yValue); - }); - }); - break; - } - default: { - seriesList.filter(isSeriesWithNumericalYValues).forEach((s) => { - acc.push(...s.data.map((d) => d.y)); - }); - } - } - - return acc; - }, []); -}; - -// Uses to get all series names array (except `pie` charts) -export const getSeriesNames = (series: ChartKitWidgetSeries[]) => { - return series.reduce((acc, s) => { - if ('name' in s && typeof s.name === 'string') { - acc.push(s.name); - } - - return acc; - }, []); -}; - -export const getOnlyVisibleSeries = (series: T[]) => { - return series.filter((s) => s.visible); -}; - -export const parseTransformStyle = (style: string | null): {x?: number; y?: number} => { - if (!style) { - return {}; - } - - const stringifiedValue = style.match(/\((.*?)\)/)?.[1] || ''; - const [xString, yString] = stringifiedValue.split(','); - const x = Number.isNaN(Number(xString)) ? undefined : Number(xString); - const y = Number.isNaN(Number(yString)) ? undefined : Number(yString); - - return {x, y}; -}; - -export const formatAxisTickLabel = (args: { - axis: PreparedAxis; - value: AxisDomain; - step?: number; -}) => { - const {axis, value, step} = args; - - switch (axis.type) { - case 'category': { - return value as string; - } - case 'datetime': { - const date = value as number; - const format = axis.labels.dateFormat || getDefaultDateFormat(step); - - return dateTime({input: date}).format(format); - } - case 'linear': - default: { - const numberFormat = { - unitRate: value && step ? getNumberUnitRate(step) : undefined, - ...axis.labels.numberFormat, - }; - return formatNumber(value as number | string, numberFormat); - } - } -}; - -/** - * Calculates the height of a text element in a horizontal SVG layout. - * - * @param {Object} args - The arguments for the function. - * @param {string} args.text - The text to be measured. - * @param {Partial} args.style - Optional style properties for the text element. - * @return {number} The height of the text element. - */ -export const getHorisontalSvgTextHeight = (args: { - text: string; - style?: Partial; -}) => { - const {text, style} = args; - const container = select(document.body).append('svg'); - const textSelection = container.append('text').text(text); - const fontSize = get(style, 'fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE); - - if (fontSize) { - textSelection.style('font-size', fontSize).style('alignment-baseline', 'after-edge'); - } - - const height = textSelection.node()?.getBoundingClientRect().height || 0; - container.remove(); - - return height; -}; - -const extractCategoryValue = (args: { - axisDirection: AxisDirection; - categories: string[]; - data: ChartKitWidgetSeriesData; -}) => { - const {axisDirection, categories, data} = args; - const dataCategory = get(data, axisDirection); - let categoryValue: string | undefined; - - if ('category' in data && data.category) { - categoryValue = data.category; - } - - if (typeof dataCategory === 'string') { - categoryValue = dataCategory; - } - - if (typeof dataCategory === 'number') { - categoryValue = categories[dataCategory]; - } - - if (isNil(categoryValue)) { - throw new Error('It seems you are trying to get non-existing category value'); - } - - return categoryValue; -}; - -export const getDataCategoryValue = (args: { - axisDirection: AxisDirection; - categories: string[]; - data: ChartKitWidgetSeriesData; -}) => { - const {axisDirection, categories, data} = args; - const categoryValue = extractCategoryValue({axisDirection, categories, data}); - - return categoryValue; -}; - -export function getClosestPointsRange(axis: PreparedAxis, points: AxisDomain[]) { - if (axis.type === 'category') { - return undefined; - } - - return (points[1] as number) - (points[0] as number); -} diff --git a/src/plugins/d3/renderer/utils/labels.ts b/src/plugins/d3/renderer/utils/labels.ts deleted file mode 100644 index 88b07901..00000000 --- a/src/plugins/d3/renderer/utils/labels.ts +++ /dev/null @@ -1,56 +0,0 @@ -import sortBy from 'lodash/sortBy'; - -import type {LabelData} from '../types'; - -export function getLeftPosition(label: LabelData) { - switch (label.textAnchor) { - case 'start': { - return label.x; - } - case 'middle': { - return label.x - label.size.width / 2; - } - case 'end': { - return label.x - label.size.width; - } - default: { - return label.x; - } - } -} - -export function getOverlappingByX(rect1: LabelData, rect2: LabelData, gap = 0) { - const left1 = getLeftPosition(rect1); - const right1 = left1 + rect1.size.width; - const left2 = getLeftPosition(rect2); - const right2 = left2 + rect2.size.width; - - return Math.max(0, Math.min(right1, right2) - Math.max(left1, left2) + gap); -} - -export function getOverlappingByY(rect1: LabelData, rect2: LabelData, gap = 0) { - const top1 = rect1.y - rect1.size.height; - const bottom1 = rect1.y; - const top2 = rect2.y - rect2.size.height; - const bottom2 = rect2.y; - - return Math.max(0, Math.min(bottom1, bottom2) - Math.max(top1, top2) + gap); -} - -export function isLabelsOverlapping(label1: T, label2: T, padding = 0) { - return Boolean( - getOverlappingByX(label1, label2, padding) && getOverlappingByY(label1, label2, padding), - ); -} - -export function filterOverlappingLabels(labels: T[]) { - const result: T[] = []; - const sorted = sortBy(labels, (d) => d.y, getLeftPosition); - sorted.forEach((label) => { - if (!result.some((l) => isLabelsOverlapping(label, l))) { - result.push(label); - } - }); - - return result; -} diff --git a/src/plugins/d3/renderer/utils/legend.ts b/src/plugins/d3/renderer/utils/legend.ts deleted file mode 100644 index a811678e..00000000 --- a/src/plugins/d3/renderer/utils/legend.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Selection} from 'd3'; - -export function createGradientRect( - container: Selection, - args: { - x?: number; - y?: number; - width: number; - height: number; - interpolator: (value: number) => string; - }, -) { - const {x = 0, y = 0, width, height, interpolator} = args; - - const n = 256; - const canvas = document.createElement('canvas'); - canvas.width = n; - canvas.height = 1; - const context = canvas.getContext('2d'); - if (!context) { - throw Error("Couldn't get canvas context"); - } - - for (let i = 0, j = n - 1; i < n; ++i) { - context.fillStyle = interpolator(i / j); - context.fillRect(i, 0, 1, height); - } - - return container - .append('image') - .attr('preserveAspectRatio', 'none') - .attr('height', height) - .attr('width', width) - .attr('x', x) - .attr('y', y) - .attr('xlink:href', canvas.toDataURL()); -} diff --git a/src/plugins/d3/renderer/utils/math.ts b/src/plugins/d3/renderer/utils/math.ts deleted file mode 100644 index 7c6ba4d5..00000000 --- a/src/plugins/d3/renderer/utils/math.ts +++ /dev/null @@ -1,61 +0,0 @@ -import isNil from 'lodash/isNil'; - -const isStringValueInPercent = (value = '') => { - return value.endsWith('%') && !Number.isNaN(Number.parseFloat(value)); -}; - -const isStringValueInPixel = (value = '') => { - return value.endsWith('px') && !Number.isNaN(Number.parseFloat(value)); -}; - -/** - * Calculates a numeric property based on the given arguments. - * - * @param {Object} args - The arguments for the calculation. - * @param {string | number | null} args.value - The value to calculate the property for. - * @param {number} args.base - The base value to use in the calculation. - * @return {number | undefined} The calculated numeric property, or undefined if the value is invalid. - * @example - * const result1 = calculateNumericProperty({value: 1}); - * console.log(result1); // Output: 1 - * const result2 = calculateNumericProperty({value: '10px'}); - * console.log(result2); // Output: 10 - * const result3 = calculateNumericProperty({value: '50%', base: 200}); - * console.log(result3); // Output: 100 - * const result4 = calculateNumericProperty({value: '50%'}); - * console.log(result4); // Output: undefined - * const result5 = calculateNumericProperty({value: 'invalid_value'}); - * console.log(result5); // Output: undefined - */ -export const calculateNumericProperty = (args: {value?: string | number | null; base?: number}) => { - const {value = '', base} = args; - - if (isNil(value)) { - return undefined; - } - - if (typeof value === 'string') { - if (isStringValueInPercent(value) && typeof base === 'number') { - const fraction = Number.parseFloat(value) / 100; - return base * fraction; - } - - if (isStringValueInPixel(value)) { - return Number.parseFloat(value); - } - - return undefined; - } - - return value; -}; - -export function calculateCos(deg: number, precision = 2) { - const factor = Math.pow(10, precision); - return Math.floor(Math.cos((Math.PI / 180) * deg) * factor) / factor; -} - -export function calculateSin(deg: number, precision = 2) { - const factor = Math.pow(10, precision); - return Math.floor(Math.sin((Math.PI / 180) * deg) * factor) / factor; -} diff --git a/src/plugins/d3/renderer/utils/series/index.ts b/src/plugins/d3/renderer/utils/series/index.ts deleted file mode 100644 index 337a6819..00000000 --- a/src/plugins/d3/renderer/utils/series/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './waterfall'; diff --git a/src/plugins/d3/renderer/utils/series/waterfall.ts b/src/plugins/d3/renderer/utils/series/waterfall.ts deleted file mode 100644 index 4ea84af2..00000000 --- a/src/plugins/d3/renderer/utils/series/waterfall.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {WaterfallSeriesData} from '../../../../../types'; -import {PreparedWaterfallSeries} from '../../hooks'; - -export function getWaterfallPointColor( - point: WaterfallSeriesData, - series: PreparedWaterfallSeries, -) { - if (point.color) { - return point.color; - } - - if (point.total) { - return series.color; - } - - if (Number(point.y) > 0) { - return series.positiveColor; - } - - return series.negativeColor; -} - -export function getWaterfallPointSubtotal( - point: WaterfallSeriesData, - series: PreparedWaterfallSeries, -) { - const pointIndex = series.data.indexOf(point); - - if (pointIndex === -1) { - return null; - } - - return series.data.reduce((sum, d, index) => { - if (index <= pointIndex) { - const value = d.total ? 0 : Number(d.y); - return sum + value; - } - - return sum; - }, 0); -} diff --git a/src/plugins/d3/renderer/utils/symbol.ts b/src/plugins/d3/renderer/utils/symbol.ts deleted file mode 100644 index 9763a1fa..00000000 --- a/src/plugins/d3/renderer/utils/symbol.ts +++ /dev/null @@ -1,41 +0,0 @@ -import {symbolCircle, symbolDiamond2, symbolSquare, symbolTriangle2} from 'd3'; - -import {SymbolType} from '../../../../constants'; - -export const getSymbolType = (index: number) => { - const scatterStyles = Object.values(SymbolType); - - return scatterStyles[index % scatterStyles.length]; -}; - -// This is an inverted triangle -// Based on https://github.com/d3/d3-shape/blob/main/src/symbol/triangle2.js -const sqrt3 = Math.sqrt(3); -const triangleDown = { - draw: (context: CanvasPath, size: number) => { - const s = Math.sqrt(size) * 0.6824; - const t = s / 2; - const u = (s * sqrt3) / 2; - context.moveTo(0, s); - context.lineTo(u, -t); - context.lineTo(-u, -t); - context.closePath(); - }, -}; - -export const getSymbol = (symbolType: `${SymbolType}`) => { - switch (symbolType) { - case SymbolType.Diamond: - return symbolDiamond2; - case SymbolType.Circle: - return symbolCircle; - case SymbolType.Square: - return symbolSquare; - case SymbolType.Triangle: - return symbolTriangle2; - case SymbolType.TriangleDown: - return triangleDown; - default: - return symbolCircle; - } -}; diff --git a/src/plugins/d3/renderer/utils/text.ts b/src/plugins/d3/renderer/utils/text.ts deleted file mode 100644 index 40492097..00000000 --- a/src/plugins/d3/renderer/utils/text.ts +++ /dev/null @@ -1,215 +0,0 @@ -import type {Selection} from 'd3'; -import {select} from 'd3-selection'; - -import {BaseTextStyle} from '../../../../types'; - -export function handleOverflowingText(tSpan: SVGTSpanElement | null, maxWidth: number) { - if (!tSpan) { - return; - } - - const svg = tSpan.closest('svg'); - if (!svg) { - return; - } - - const textNode = tSpan.closest('text'); - const angle = - Array.from(textNode?.transform.baseVal || []).find((item) => item.angle)?.angle || 0; - - const revertRotation = svg.createSVGTransform(); - revertRotation.setRotate(-angle, 0, 0); - textNode?.transform.baseVal.appendItem(revertRotation); - - let text = tSpan.textContent || ''; - let textLength = tSpan.getBoundingClientRect()?.width || 0; - - while (textLength > maxWidth && text.length > 1) { - text = text.slice(0, -1); - tSpan.textContent = text + '…'; - textLength = tSpan.getBoundingClientRect()?.width || 0; - } - - textNode?.transform.baseVal.removeItem(textNode?.transform.baseVal.length - 1); -} - -export function setEllipsisForOverflowText( - selection: Selection, - maxWidth: number, -) { - const text = selection.text(); - selection.text(null).append('title').text(text); - const tSpan = selection.append('tspan').text(text).style('alignment-baseline', 'inherit'); - handleOverflowingText(tSpan.node(), maxWidth); -} - -export function setEllipsisForOverflowTexts( - selection: Selection, - maxWidth: ((datum: T) => number) | number, -) { - selection.each(function (datum) { - const textMaxWidth = typeof maxWidth === 'function' ? maxWidth(datum) : maxWidth; - setEllipsisForOverflowText(select(this), textMaxWidth); - }); -} - -export function hasOverlappingLabels({ - width, - labels, - padding = 0, - style, -}: { - width: number; - labels: string[]; - style?: BaseTextStyle; - padding?: number; -}) { - const maxWidth = (width - padding * (labels.length - 1)) / labels.length; - - const textElement = select(document.body) - .append('text') - .style('font-size', style?.fontSize || ''); - - const result = labels.some((label) => { - const textWidth = textElement.text(label).node()?.getBoundingClientRect()?.width || 0; - return textWidth > maxWidth; - }); - - textElement.remove(); - - return result; -} - -function renderLabels( - selection: Selection, - { - labels, - style = {}, - attrs = {}, - }: { - labels: string[]; - style?: Partial; - attrs?: Record; - }, -) { - const text = selection.append('g').append('text'); - - text.style('font-size', style.fontSize || ''); - text.style('font-weight', style.fontWeight || ''); - - Object.entries(attrs).forEach(([name, value]) => { - text.attr(name, value); - }); - - text.selectAll('tspan') - .data(labels) - .enter() - .append('tspan') - .attr('x', 0) - .attr('dy', 0) - .text((d) => d); - - return text; -} - -export function getLabelsSize({ - labels, - style, - rotation, - html, -}: { - labels: string[]; - style?: BaseTextStyle; - rotation?: number; - html?: boolean; -}) { - if (!labels.filter(Boolean).length) { - return {maxHeight: 0, maxWidth: 0}; - } - - const container = select(document.body) - .append('div') - .attr('class', 'chartkit chartkit-theme_common'); - - const result = {maxHeight: 0, maxWidth: 0}; - let labelWrapper: HTMLElement | null; - if (html) { - labelWrapper = container.append('div').style('position', 'absolute').node(); - const {height, width} = labels.reduce( - (acc, l) => { - if (labelWrapper) { - labelWrapper.innerHTML = l; - } - const rect = labelWrapper?.getBoundingClientRect(); - return { - width: Math.max(acc.width, rect?.width ?? 0), - height: Math.max(acc.height, rect?.height ?? 0), - }; - }, - {height: 0, width: 0}, - ); - - result.maxWidth = width; - result.maxHeight = height; - } else { - const svg = container.append('svg'); - const textSelection = renderLabels(svg, {labels, style}); - if (rotation) { - textSelection - .attr('text-anchor', rotation > 0 ? 'start' : 'end') - .style('transform', `rotate(${rotation}deg)`); - } - - const rect = (svg.select('g').node() as Element)?.getBoundingClientRect(); - result.maxWidth = rect?.width ?? 0; - result.maxHeight = rect?.height ?? 0; - } - - container.remove(); - - return result; -} - -export type TextRow = {text: string; y: number}; - -export function wrapText(args: {text: string; style?: BaseTextStyle; width: number}): TextRow[] { - const {text, style, width} = args; - - const height = getLabelsSize({ - labels: [text], - style: style, - }).maxHeight; - // @ts-ignore - const segmenter = new Intl.Segmenter([], {granularity: 'word'}); - const segments = Array.from(segmenter.segment(text)); - - return segments.reduce((acc, s) => { - const item = s as {isWordLike: boolean; segment: string}; - if (!acc.length) { - acc.push({ - text: '', - y: acc.length * height, - }); - } - - let lastRow = acc[acc.length - 1]; - - if ( - item.isWordLike && - getLabelsSize({ - labels: [lastRow.text + item.segment], - style, - }).maxWidth > width - ) { - lastRow = { - text: '', - y: acc.length * height, - }; - acc.push(lastRow); - } - - lastRow.text += item.segment; - - return acc; - }, []); -} diff --git a/src/plugins/d3/renderer/utils/time.ts b/src/plugins/d3/renderer/utils/time.ts deleted file mode 100644 index 9c715c16..00000000 --- a/src/plugins/d3/renderer/utils/time.ts +++ /dev/null @@ -1,39 +0,0 @@ -export const TIME_UNITS: Record = { - millisecond: 1, - second: 1000, - minute: 60000, - hour: 3600000, - day: 24 * 3600000, - week: 7 * 24 * 3600000, - month: 28 * 24 * 3600000, - year: 364 * 24 * 3600000, -}; - -export const DATETIME_LABEL_FORMATS: Record = { - millisecond: 'DD.MM.YY HH:mm:ss.SSS', - second: 'DD.MM.YY HH:mm:ss', - minute: 'DD.MM.YY HH:mm', - hour: 'DD.MM.YY HH:mm', - day: 'DD.MM.YY', - week: 'DD.MM.YY', - month: "MMM 'YY", - year: 'YYYY', -}; - -function getTimeUnit(range: number): keyof typeof TIME_UNITS { - const units = Object.keys(TIME_UNITS); - const index = units.findIndex((unit) => range < TIME_UNITS[unit]); - return index === -1 ? 'year' : units[index - 1]; -} - -export function getDefaultDateFormat(range?: number) { - if (range) { - const unit = getTimeUnit(range); - - if (unit in DATETIME_LABEL_FORMATS) { - return DATETIME_LABEL_FORMATS[unit]; - } - } - - return DATETIME_LABEL_FORMATS.day; -} diff --git a/src/plugins/d3/renderer/validation/__mocks__/index.ts b/src/plugins/d3/renderer/validation/__mocks__/index.ts deleted file mode 100644 index a7f5638c..00000000 --- a/src/plugins/d3/renderer/validation/__mocks__/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -import {ChartKitWidgetData} from '../../../../../types'; - -export const XY_SERIES: Record = { - INVALID_CATEGORY_X: { - series: { - data: [{type: 'scatter', data: [{x: undefined, y: 1}], name: 'Series'}], - }, - xAxis: {type: 'category'}, - }, - INVALID_CATEGORY_Y: { - series: { - data: [{type: 'scatter', data: [{x: 1, y: undefined}], name: 'Series'}], - }, - yAxis: [{type: 'category'}], - }, - INVALID_DATETIME_X: { - series: { - data: [{type: 'scatter', data: [{x: undefined, y: 1}], name: 'Series'}], - }, - xAxis: {type: 'datetime'}, - }, - INVALID_DATETIME_Y: { - series: { - data: [{type: 'scatter', data: [{x: undefined, y: 1}], name: 'Series'}], - }, - yAxis: [{type: 'datetime'}], - }, - INVALID_LINEAR_X: { - series: { - data: [{type: 'scatter', data: [{x: 'str', y: 1}], name: 'Series'}], - }, - }, - INVALID_LINEAR_Y: { - series: { - data: [{type: 'scatter', data: [{x: 1, y: 'str'}], name: 'Series'}], - }, - }, -}; - -export const PIE_SERIES: Record = { - INVALID_VALUE: { - series: { - // @ts-expect-error - data: [{type: 'pie', data: [{value: undefined, name: 'Series'}]}], - }, - }, -}; diff --git a/src/plugins/d3/renderer/validation/__tests__/validation.test.ts b/src/plugins/d3/renderer/validation/__tests__/validation.test.ts deleted file mode 100644 index 91caafb6..00000000 --- a/src/plugins/d3/renderer/validation/__tests__/validation.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import {validateData} from '../'; -import {CHARTKIT_ERROR_CODE, ChartKitError} from '../../../../../libs'; -import {ChartKitWidgetData} from '../../../../../types'; -import {PIE_SERIES, XY_SERIES} from '../__mocks__'; - -describe('plugins/d3/validation', () => { - test.each([undefined, null, {}, {series: {}}, {series: {data: []}}])( - 'validateData should throw an error in case of empty data (data: %j)', - (data) => { - let error: ChartKitError | null = null; - - try { - validateData(data); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.NO_DATA); - }, - ); - - test.each([ - {series: {data: [{data: [{x: 1, y: 1}]}]}}, - {series: {data: [{type: 'invalid-type', data: [{x: 1, y: 1}]}]}}, - ])('validateData should throw an error in case of incorrect series type (data: %j)', (data) => { - let error: ChartKitError | null = null; - - try { - validateData(data); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }); - - test.each([ - XY_SERIES.INVALID_CATEGORY_X, - XY_SERIES.INVALID_CATEGORY_Y, - XY_SERIES.INVALID_DATETIME_X, - XY_SERIES.INVALID_DATETIME_Y, - XY_SERIES.INVALID_LINEAR_X, - XY_SERIES.INVALID_LINEAR_Y, - ])( - '[XY Series] validateData should throw an error in case of invalid data (data: %j)', - (data) => { - let error: ChartKitError | null = null; - - try { - validateData(data); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }, - ); - - test.each([PIE_SERIES.INVALID_VALUE])( - '[Pie Series] validateData should throw an error in case of invalid data (data: %j)', - (data) => { - let error: ChartKitError | null = null; - - try { - validateData(data); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }, - ); - - test.each([ - {series: {data: [{type: 'area', stacking: 'notNormal', data: [{x: 1, y: 1}]}]}}, - {series: {data: [{type: 'bar-x', stacking: 'notNormal', data: [{x: 1, y: 1}]}]}}, - {series: {data: [{type: 'bar-y', stacking: 'notNormal', data: [{x: 1, y: 1}]}]}}, - ])( - 'validateData should throw an error in case of invalid stacking value (data: %j)', - (data) => { - let error: ChartKitError | null = null; - - try { - validateData(data as ChartKitWidgetData); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }, - ); - - test.each([ - [[{name: '1'} /* error */]], - [[{name: '1'}, {name: '2', parentId: '1'} /* error */]], - [ - [ - {name: '1', value: 1}, // error - {name: '2', parentId: '1', value: 1}, - ], - ], - [ - [ - {name: '1'}, - {name: '2', parentId: '1', value: 1}, // error - {name: '3', parentId: '2', value: 1}, - {name: '4', parentId: '2', value: 1}, - ], - ], - ])( - '[Treemap Series] validateData should throw an error in case of invalid data (data: %j)', - (data) => { - let error: ChartKitError | null = null; - - try { - validateData({ - series: { - data: [ - { - type: 'treemap', - data, - }, - ] as ChartKitWidgetData['series']['data'], - }, - }); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }, - ); - - test('validateData should throw an error in case of invalid axis index', () => { - const data = {series: {data: [{type: 'line', yAxis: 5, data: [{x: 1, y: 1}]}]}}; - let error: ChartKitError | null = null; - - try { - validateData(data as ChartKitWidgetData); - } catch (e) { - error = e as ChartKitError; - } - - expect(error?.code).toEqual(CHARTKIT_ERROR_CODE.INVALID_DATA); - }); -}); diff --git a/src/plugins/d3/renderer/validation/index.ts b/src/plugins/d3/renderer/validation/index.ts deleted file mode 100644 index 0b85ed8a..00000000 --- a/src/plugins/d3/renderer/validation/index.ts +++ /dev/null @@ -1,273 +0,0 @@ -import get from 'lodash/get'; -import isEmpty from 'lodash/isEmpty'; - -import {SeriesType} from '../../../../constants'; -import {i18n} from '../../../../i18n'; -import {CHARTKIT_ERROR_CODE, ChartKitError} from '../../../../libs'; -import { - AreaSeries, - BarXSeries, - BarYSeries, - ChartKitWidgetData, - ChartKitWidgetSeries, - ChartKitWidgetXAxis, - ChartKitWidgetYAxis, - LineSeries, - PieSeries, - ScatterSeries, - TreemapSeries, -} from '../../../../types'; -import {DEFAULT_AXIS_TYPE} from '../constants'; - -type XYSeries = ScatterSeries | BarXSeries | BarYSeries | LineSeries | AreaSeries; - -const AVAILABLE_SERIES_TYPES = Object.values(SeriesType); - -const validateXYSeries = (args: { - series: XYSeries; - xAxis?: ChartKitWidgetXAxis; - yAxis?: ChartKitWidgetYAxis[]; -}) => { - const {series, xAxis, yAxis = []} = args; - - const yAxisIndex = get(series, 'yAxis', 0); - const seriesYAxis = yAxis[yAxisIndex]; - if (yAxisIndex !== 0 && typeof seriesYAxis === 'undefined') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-y-axis-index', { - index: yAxisIndex, - }), - }); - } - - const xType = get(xAxis, 'type', DEFAULT_AXIS_TYPE); - const yType = get(seriesYAxis, 'type', DEFAULT_AXIS_TYPE); - series.data.forEach(({x, y}) => { - switch (xType) { - case 'category': { - if (typeof x !== 'string' && typeof x !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-category-data-point', { - key: 'x', - seriesName: series.name, - }), - }); - } - - break; - } - case 'datetime': { - if (typeof x !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-datetime-data-point', { - key: 'x', - seriesName: series.name, - }), - }); - } - - break; - } - case 'linear': { - if (typeof x !== 'number' && x !== null) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-linear-data-point', { - key: 'x', - seriesName: series.name, - }), - }); - } - } - } - switch (yType) { - case 'category': { - if (typeof y !== 'string' && typeof y !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-category-data-point', { - key: 'y', - seriesName: series.name, - }), - }); - } - - break; - } - case 'datetime': { - if (typeof y !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-datetime-data-point', { - key: 'y', - seriesName: series.name, - }), - }); - } - - break; - } - case 'linear': { - if (typeof y !== 'number' && y !== null) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-axis-linear-data-point', { - key: 'y', - seriesName: series.name, - }), - }); - } - } - } - }); -}; - -const validatePieSeries = ({series}: {series: PieSeries}) => { - series.data.forEach(({value}) => { - if (typeof value !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-pie-data-value'), - }); - } - }); -}; - -const validateStacking = ({series}: {series: AreaSeries | BarXSeries | BarYSeries}) => { - const availableStackingValues = ['normal', 'percent']; - - if (series.stacking && !availableStackingValues.includes(series.stacking)) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-series-property', { - key: 'stacking', - values: availableStackingValues, - }), - }); - } -}; - -const validateTreemapSeries = ({series}: {series: TreemapSeries}) => { - const parentIds: Record = {}; - series.data.forEach((d) => { - if (d.parentId && !parentIds[d.parentId]) { - parentIds[d.parentId] = true; - } - }); - series.data.forEach((d) => { - let idOrName = d.id; - if (!idOrName) { - idOrName = Array.isArray(d.name) ? d.name.join() : d.name; - } - - if (parentIds[idOrName] && typeof d.value === 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-treemap-redundant-value', { - id: d.id, - name: d.name, - }), - }); - } - - if (!parentIds[idOrName] && typeof d.value !== 'number') { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-treemap-missing-value', { - id: d.id, - name: d.name, - }), - }); - } - }); -}; - -const validateSeries = (args: { - series: ChartKitWidgetSeries; - xAxis?: ChartKitWidgetXAxis; - yAxis?: ChartKitWidgetYAxis[]; -}) => { - const {series, xAxis, yAxis} = args; - - if (!AVAILABLE_SERIES_TYPES.includes(series.type)) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: i18n('error', 'label_invalid-series-type', { - types: AVAILABLE_SERIES_TYPES.join(', '), - }), - }); - } - - switch (series.type) { - case 'area': - case 'bar-y': - case 'bar-x': { - validateXYSeries({series, xAxis, yAxis}); - validateStacking({series}); - break; - } - case 'line': - case 'scatter': { - validateXYSeries({series, xAxis, yAxis}); - break; - } - case 'pie': { - validatePieSeries({series}); - break; - } - case 'treemap': { - validateTreemapSeries({series}); - } - } -}; - -const countSeriesByType = (args: { - series: ChartKitWidgetSeries[]; - type: ChartKitWidgetSeries['type']; -}) => { - const {series, type} = args; - let count = 0; - - series.forEach((s) => { - if (s.type === type) { - count += 1; - } - }); - - return count; -}; - -export const validateData = (data?: ChartKitWidgetData) => { - if (isEmpty(data) || isEmpty(data.series) || isEmpty(data.series.data)) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.NO_DATA, - message: i18n('error', 'label_no-data'), - }); - } - - if (data.series.data.some((s) => isEmpty(s.data))) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: 'You should specify data for all series', - }); - } - - const treemapSeriesCount = countSeriesByType({ - series: data.series.data, - type: SeriesType.Treemap, - }); - - if (treemapSeriesCount > 1) { - throw new ChartKitError({ - code: CHARTKIT_ERROR_CODE.INVALID_DATA, - message: 'It looks like you are trying to define more than one "treemap" series.', - }); - } - - data.series.data.forEach((series) => { - validateSeries({series, yAxis: data.yAxis, xAxis: data.xAxis}); - }); -}; diff --git a/src/plugins/d3/types.ts b/src/plugins/d3/types.ts index e1fbd1f0..6e1c4bfc 100644 --- a/src/plugins/d3/types.ts +++ b/src/plugins/d3/types.ts @@ -1,5 +1,5 @@ -import type {ChartKitWidgetData} from '../../types/widget-data'; +import type {ChartData} from '@gravity-ui/charts'; export type D3WidgetData = { - data: ChartKitWidgetData; + data: ChartData; }; diff --git a/src/plugins/d3/utils/index.ts b/src/plugins/d3/utils/index.ts deleted file mode 100644 index 21d6fd59..00000000 --- a/src/plugins/d3/utils/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {pieCenterText} from './pie-center-text'; - -export const CustomShapeRenderer = { - pieCenterText, -}; diff --git a/src/plugins/d3/utils/pie-center-text.ts b/src/plugins/d3/utils/pie-center-text.ts deleted file mode 100644 index e2a3ba24..00000000 --- a/src/plugins/d3/utils/pie-center-text.ts +++ /dev/null @@ -1,31 +0,0 @@ -import {create} from 'd3-selection'; -import get from 'lodash/get'; - -import {getLabelsSize} from '../renderer/utils'; - -const MAX_FONT_SIZE = 64; - -export function pieCenterText(text: string, options?: {padding?: number}) { - if (!text) { - return undefined; - } - - const padding = get(options, 'padding', 12); - - return function (args: {series: {innerRadius: number}}) { - let fontSize = MAX_FONT_SIZE; - - const textSize = getLabelsSize({labels: [text], style: {fontSize: `${fontSize}px`}}); - fontSize = (fontSize * (args.series.innerRadius - padding) * 2) / textSize.maxWidth; - - const container = create('svg:g'); - container - .append('text') - .text(text) - .attr('text-anchor', 'middle') - .attr('alignment-baseline', 'middle') - .style('font-size', `${fontSize}px`); - - return container.node(); - }; -} diff --git a/src/types/index.ts b/src/types/index.ts index d881e3a4..02e931b8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -5,6 +5,7 @@ import {ChartKitError} from '../libs'; import type {ChartKitWidget} from './widget'; export type {ChartKitHolidays} from './misc'; +// TODO: remove in the next major. This types should be consumed directly from '@gravity-ui/charts' export * from './widget-data'; export type ChartKitLang = 'ru' | 'en'; diff --git a/src/types/widget-data/pie.ts b/src/types/widget-data/pie.ts index 711fe7fb..efe392c6 100644 --- a/src/types/widget-data/pie.ts +++ b/src/types/widget-data/pie.ts @@ -1,4 +1,4 @@ -import {BaseType} from 'd3'; +import type {BaseType} from 'd3'; import {SeriesType} from '../../constants';