diff --git a/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/group.ts b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/group.ts new file mode 100644 index 0000000000..9dc1511784 --- /dev/null +++ b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/group.ts @@ -0,0 +1,190 @@ +import { registerRegressionLine } from '../../../../../src/components/regression-line/regression-line'; +import { appendScatterRegressionLineConfig } from './../../../../../src/components/scatter-regression-line'; +import { default as VChart } from '@visactor/vchart'; + +const data = [ + { continent: 'Americas', Country: 'Argentina', LifeExpectancy: 75.32, GDP: 12779.37964, Population: 40301927 }, + { continent: 'Americas', Country: 'Brazil', LifeExpectancy: 72.39, GDP: 9065.800825, Population: 190010647 }, + { continent: 'Americas', Country: 'Canada', LifeExpectancy: 80.653, GDP: 36319.23501, Population: 33390141 }, + { continent: 'Americas', Country: 'Chile', LifeExpectancy: 78.553, GDP: 13171.63885, Population: 16284741 }, + { continent: 'Americas', Country: 'Colombia', LifeExpectancy: 72.889, GDP: 7006.580419, Population: 44227550 }, + { continent: 'Americas', Country: 'Costa Rica', LifeExpectancy: 78.782, GDP: 9645.06142, Population: 4133884 }, + { continent: 'Americas', Country: 'Cuba', LifeExpectancy: 78.273, GDP: 8948.102923, Population: 11416987 }, + { + continent: 'Americas', + Country: 'Dominican Republic', + LifeExpectancy: 72.235, + GDP: 6025.374752, + Population: 9319622 + }, + { continent: 'Americas', Country: 'Ecuador', LifeExpectancy: 74.994, GDP: 6873.262326, Population: 13755680 }, + { continent: 'Americas', Country: 'El Salvador', LifeExpectancy: 71.878, GDP: 5728.353514, Population: 6939688 }, + { continent: 'Americas', Country: 'Guatemala', LifeExpectancy: 70.259, GDP: 5186.050003, Population: 12572928 }, + { continent: 'Americas', Country: 'Honduras', LifeExpectancy: 70.198, GDP: 3548.330846, Population: 7483763 }, + { continent: 'Americas', Country: 'Jamaica', LifeExpectancy: 72.567, GDP: 7320.880262, Population: 2780132 }, + { continent: 'Americas', Country: 'Mexico', LifeExpectancy: 76.195, GDP: 11977.57496, Population: 108700891 }, + { continent: 'Americas', Country: 'Nicaragua', LifeExpectancy: 72.899, GDP: 2749.320965, Population: 5675356 }, + { continent: 'Americas', Country: 'Panama', LifeExpectancy: 75.537, GDP: 9809.185636, Population: 3242173 }, + { continent: 'Americas', Country: 'Paraguay', LifeExpectancy: 71.752, GDP: 4172.838464, Population: 6667147 }, + { continent: 'Americas', Country: 'Peru', LifeExpectancy: 71.421, GDP: 7408.905561, Population: 28674757 }, + { continent: 'Americas', Country: 'Puerto Rico', LifeExpectancy: 78.746, GDP: 19328.70901, Population: 3942491 }, + { + continent: 'Americas', + Country: 'Trinidad and Tobago', + LifeExpectancy: 69.819, + GDP: 18008.50924, + Population: 1056608 + }, + { continent: 'Americas', Country: 'United States', LifeExpectancy: 78.242, GDP: 42951.65309, Population: 301139947 }, + { continent: 'Americas', Country: 'Uruguay', LifeExpectancy: 76.384, GDP: 10611.46299, Population: 3447496 }, + { continent: 'Americas', Country: 'Venezuela', LifeExpectancy: 73.747, GDP: 11415.80569, Population: 26084662 }, + { continent: 'Asia', Country: 'China', LifeExpectancy: 72.961, GDP: 4959.114854, Population: 1318683096 }, + { continent: 'Asia', Country: 'Hong Kong, China', LifeExpectancy: 82.208, GDP: 39724.97867, Population: 6980412 }, + { continent: 'Asia', Country: 'Japan', LifeExpectancy: 82.603, GDP: 31656.06806, Population: 127467972 }, + { continent: 'Asia', Country: 'Korea, Dem. Rep.', LifeExpectancy: 67.297, GDP: 1593.06548, Population: 23301725 }, + { continent: 'Asia', Country: 'Korea, Rep.', LifeExpectancy: 78.623, GDP: 23348.13973, Population: 49044790 }, + { continent: 'Europe', Country: 'Albania', LifeExpectancy: 76.423, GDP: 5937.029526, Population: 3600523 }, + { continent: 'Europe', Country: 'Austria', LifeExpectancy: 79.829, GDP: 36126.4927, Population: 8199783 }, + { continent: 'Europe', Country: 'Belgium', LifeExpectancy: 79.441, GDP: 33692.60508, Population: 10392226 }, + { + continent: 'Europe', + Country: 'Bosnia and Herzegovina', + LifeExpectancy: 74.852, + GDP: 7446.298803, + Population: 4552198 + }, + { continent: 'Europe', Country: 'Bulgaria', LifeExpectancy: 73.005, GDP: 10680.79282, Population: 7322858 }, + { continent: 'Europe', Country: 'Croatia', LifeExpectancy: 75.748, GDP: 14619.22272, Population: 4493312 }, + { continent: 'Europe', Country: 'Czech Republic', LifeExpectancy: 76.486, GDP: 22833.30851, Population: 10228744 }, + { continent: 'Europe', Country: 'Denmark', LifeExpectancy: 78.332, GDP: 35278.41874, Population: 5468120 }, + { continent: 'Europe', Country: 'Finland', LifeExpectancy: 79.313, GDP: 33207.0844, Population: 5238460 }, + { continent: 'Europe', Country: 'France', LifeExpectancy: 80.657, GDP: 30470.0167, Population: 61083916 }, + { continent: 'Europe', Country: 'Germany', LifeExpectancy: 79.406, GDP: 32170.37442, Population: 82400996 }, + { continent: 'Europe', Country: 'Greece', LifeExpectancy: 79.483, GDP: 27538.41188, Population: 10706290 }, + { continent: 'Europe', Country: 'Hungary', LifeExpectancy: 73.338, GDP: 18008.94444, Population: 9956108 }, + { continent: 'Europe', Country: 'Iceland', LifeExpectancy: 81.757, GDP: 36180.78919, Population: 301931 }, + { continent: 'Europe', Country: 'Ireland', LifeExpectancy: 78.885, GDP: 40675.99635, Population: 4109086 }, + { continent: 'Europe', Country: 'Italy', LifeExpectancy: 80.546, GDP: 28569.7197, Population: 58147733 }, + { continent: 'Europe', Country: 'Montenegro', LifeExpectancy: 74.543, GDP: 9253.896111, Population: 684736 }, + { continent: 'Europe', Country: 'Netherlands', LifeExpectancy: 79.762, GDP: 36797.93332, Population: 16570613 }, + { continent: 'Europe', Country: 'Norway', LifeExpectancy: 80.196, GDP: 49357.19017, Population: 4627926 }, + { continent: 'Europe', Country: 'Poland', LifeExpectancy: 75.563, GDP: 15389.92468, Population: 38518241 }, + { continent: 'Europe', Country: 'Portugal', LifeExpectancy: 78.098, GDP: 20509.64777, Population: 10642836 }, + { continent: 'Europe', Country: 'Romania', LifeExpectancy: 72.476, GDP: 10808.47561, Population: 22276056 }, + { continent: 'Europe', Country: 'Serbia', LifeExpectancy: 74.002, GDP: 9786.534714, Population: 10150265 }, + { continent: 'Europe', Country: 'Slovak Republic', LifeExpectancy: 74.663, GDP: 18678.31435, Population: 5447502 }, + { continent: 'Europe', Country: 'Slovenia', LifeExpectancy: 77.926, GDP: 25768.25759, Population: 2009245 }, + { continent: 'Europe', Country: 'Spain', LifeExpectancy: 80.941, GDP: 28821.0637, Population: 40448191 }, + { continent: 'Europe', Country: 'Sweden', LifeExpectancy: 80.884, GDP: 33859.74835, Population: 9031088 }, + { continent: 'Europe', Country: 'Switzerland', LifeExpectancy: 81.701, GDP: 37506.41907, Population: 7554661 }, + { continent: 'Europe', Country: 'Turkey', LifeExpectancy: 71.777, GDP: 8458.276384, Population: 71158647 }, + { continent: 'Europe', Country: 'United Kingdom', LifeExpectancy: 79.425, GDP: 33203.26128, Population: 60776238 }, + { continent: 'Oceania', Country: 'Australia', LifeExpectancy: 81.235, GDP: 34435.36744, Population: 20434176 }, + { continent: 'Oceania', Country: 'New Zealand', LifeExpectancy: 80.204, GDP: 25185.00911, Population: 4115771 } +]; + +function logScale(value, domain, range) { + // 计算域和范围的对数 + const logDomain = domain.map(x => (x !== 0 ? Math.log10(x) : 0)); + const logRange = range.map(x => Math.log10(x)); + + // 计算值在域内的位置,将其映射到范围内 + const t = (Math.log10(value) - logDomain[0]) / (logDomain[1] - logDomain[0]); + const newValue = (logRange[1] - logRange[0]) * t + logRange[0]; + + // 返回映射后的值,还原对数缩放 + return Math.pow(10, newValue); +} + +// 图表配置 +const spec = { + type: 'common', + series: [ + { + type: 'scatter', + xField: 'GDP', + yField: 'LifeExpectancy', + seriesField: 'continent', + sizeField: 'Population', + size: d => logScale(d.Population, [0, Math.max(...data.map(d => d.Population))], [1, 20]) + } + ], + crosshair: { + yField: { + visible: true, + line: { visible: true, type: 'line' }, + label: { + visible: true // label 默认关闭 + } + }, + xField: { + visible: true, + line: { visible: true, type: 'line' }, + label: { + visible: true // label 默认关闭 + } + } + }, + + data: [ + { + id: 'data', + values: data + } + ], + axes: [ + { + orient: 'left', + type: 'linear', + range: { + min: Math.min(...data.map(d => d.LifeExpectancy)), + max: Math.max(...data.map(d => d.LifeExpectancy)) + }, + title: { + visible: true, + text: 'LifeExpectancy' + }, + domainLine: { + visible: true + } + }, + { + orient: 'bottom', + type: 'linear', + title: { + visible: true, + text: 'GDP' + }, + domainLine: { + visible: true + } + } + ], + legends: [ + { + visible: true, + orient: 'right' + } + ], + regressionLine: { + type: 'linear' + } +}; + +const run = () => { + registerRegressionLine(); + appendScatterRegressionLineConfig(spec); + + const cs = new VChart(spec, { + dom: document.getElementById('chart') as HTMLElement, + //theme: 'dark', + onError: err => { + console.error(err); + } + }); + + cs.renderSync(); + + window['vchart'] = cs; +}; +run(); diff --git a/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/linear.ts b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/linear.ts index 66d451d323..af3755dd03 100644 --- a/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/linear.ts +++ b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/linear.ts @@ -523,13 +523,11 @@ const run = () => { polynomialDegree: 3, line: { style: { - stroke: 'green', lineWidth: 2 } }, confidenceInterval: { style: { - fill: 'green', fillOpacity: 0.2 } }, diff --git a/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/logistic.ts b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/logistic.ts new file mode 100644 index 0000000000..df935dec91 --- /dev/null +++ b/packages/vchart-extension/__tests__/runtime/browser/test-page/scatter-regression-line/logistic.ts @@ -0,0 +1,526 @@ +import { registerRegressionLine } from '../../../../../src/components/regression-line/regression-line'; +import { appendScatterRegressionLineConfig } from '../../../../../src/components/scatter-regression-line'; +import { default as VChart } from '@visactor/vchart'; + +const data = [ + { name: 'chevrolet chevelle malibu', milesPerGallon: 18, cylinders: 8, horsepower: 130 }, + { name: 'buick skylark 320', milesPerGallon: 15, cylinders: 8, horsepower: 165 }, + { name: 'plymouth satellite', milesPerGallon: 18, cylinders: 8, horsepower: 150 }, + { name: 'amc rebel sst', milesPerGallon: 16, cylinders: 8, horsepower: 150 }, + { name: 'ford torino', milesPerGallon: 17, cylinders: 8, horsepower: 140 }, + { name: 'ford galaxie 500', milesPerGallon: 15, cylinders: 8, horsepower: 198 }, + { name: 'chevrolet impala', milesPerGallon: 14, cylinders: 8, horsepower: 220 }, + { name: 'plymouth fury iii', milesPerGallon: 14, cylinders: 8, horsepower: 215 }, + { name: 'pontiac catalina', milesPerGallon: 14, cylinders: 8, horsepower: 225 }, + { name: 'amc ambassador dpl', milesPerGallon: 15, cylinders: 8, horsepower: 190 }, + { name: 'citroen ds-21 pallas', milesPerGallon: 0, cylinders: 4, horsepower: 115 }, + { name: 'chevrolet chevelle concours (sw)', milesPerGallon: 0, cylinders: 8, horsepower: 165 }, + { name: 'ford torino (sw)', milesPerGallon: 0, cylinders: 8, horsepower: 153 }, + { name: 'plymouth satellite (sw)', milesPerGallon: 0, cylinders: 8, horsepower: 175 }, + { name: 'amc rebel sst (sw)', milesPerGallon: 0, cylinders: 8, horsepower: 175 }, + { name: 'dodge challenger se', milesPerGallon: 15, cylinders: 8, horsepower: 170 }, + { name: "plymouth 'cuda 340", milesPerGallon: 14, cylinders: 8, horsepower: 160 }, + { name: 'ford mustang boss 302', milesPerGallon: 0, cylinders: 8, horsepower: 140 }, + { name: 'chevrolet monte carlo', milesPerGallon: 15, cylinders: 8, horsepower: 150 }, + { name: 'buick estate wagon (sw)', milesPerGallon: 14, cylinders: 8, horsepower: 225 }, + { name: 'toyota corona mark ii', milesPerGallon: 24, cylinders: 4, horsepower: 95 }, + { name: 'plymouth duster', milesPerGallon: 22, cylinders: 6, horsepower: 95 }, + { name: 'amc hornet', milesPerGallon: 18, cylinders: 6, horsepower: 97 }, + { name: 'ford maverick', milesPerGallon: 21, cylinders: 6, horsepower: 85 }, + { name: 'datsun pl510', milesPerGallon: 27, cylinders: 4, horsepower: 88 }, + { name: 'volkswagen 1131 deluxe sedan', milesPerGallon: 26, cylinders: 4, horsepower: 46 }, + { name: 'peugeot 504', milesPerGallon: 25, cylinders: 4, horsepower: 87 }, + { name: 'audi 100 ls', milesPerGallon: 24, cylinders: 4, horsepower: 90 }, + { name: 'saab 99e', milesPerGallon: 25, cylinders: 4, horsepower: 95 }, + { name: 'bmw 2002', milesPerGallon: 26, cylinders: 4, horsepower: 113 }, + { name: 'amc gremlin', milesPerGallon: 21, cylinders: 6, horsepower: 90 }, + { name: 'ford f250', milesPerGallon: 10, cylinders: 8, horsepower: 215 }, + { name: 'chevy c20', milesPerGallon: 10, cylinders: 8, horsepower: 200 }, + { name: 'dodge d200', milesPerGallon: 11, cylinders: 8, horsepower: 210 }, + { name: 'hi 1200d', milesPerGallon: 9, cylinders: 8, horsepower: 193 }, + { name: 'datsun pl510', milesPerGallon: 27, cylinders: 4, horsepower: 88 }, + { name: 'chevrolet vega 2300', milesPerGallon: 28, cylinders: 4, horsepower: 90 }, + { name: 'toyota corona', milesPerGallon: 25, cylinders: 4, horsepower: 95 }, + { name: 'ford pinto', milesPerGallon: 25, cylinders: 4, horsepower: 0 }, + { name: 'volkswagen super beetle 117', milesPerGallon: 0, cylinders: 4, horsepower: 48 }, + { name: 'amc gremlin', milesPerGallon: 19, cylinders: 6, horsepower: 100 }, + { name: 'plymouth satellite custom', milesPerGallon: 16, cylinders: 6, horsepower: 105 }, + { name: 'chevrolet chevelle malibu', milesPerGallon: 17, cylinders: 6, horsepower: 100 }, + { name: 'ford torino 500', milesPerGallon: 19, cylinders: 6, horsepower: 88 }, + { name: 'amc matador', milesPerGallon: 18, cylinders: 6, horsepower: 100 }, + { name: 'chevrolet impala', milesPerGallon: 14, cylinders: 8, horsepower: 165 }, + { name: 'pontiac catalina brougham', milesPerGallon: 14, cylinders: 8, horsepower: 175 }, + { name: 'ford galaxie 500', milesPerGallon: 14, cylinders: 8, horsepower: 153 }, + { name: 'plymouth fury iii', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'dodge monaco (sw)', milesPerGallon: 12, cylinders: 8, horsepower: 180 }, + { name: 'ford country squire (sw)', milesPerGallon: 13, cylinders: 8, horsepower: 170 }, + { name: 'pontiac safari (sw)', milesPerGallon: 13, cylinders: 8, horsepower: 175 }, + { name: 'amc hornet sportabout (sw)', milesPerGallon: 18, cylinders: 6, horsepower: 110 }, + { name: 'chevrolet vega (sw)', milesPerGallon: 22, cylinders: 4, horsepower: 72 }, + { name: 'pontiac firebird', milesPerGallon: 19, cylinders: 6, horsepower: 100 }, + { name: 'ford mustang', milesPerGallon: 18, cylinders: 6, horsepower: 88 }, + { name: 'mercury capri 2000', milesPerGallon: 23, cylinders: 4, horsepower: 86 }, + { name: 'opel 1900', milesPerGallon: 28, cylinders: 4, horsepower: 90 }, + { name: 'peugeot 304', milesPerGallon: 30, cylinders: 4, horsepower: 70 }, + { name: 'fiat 124b', milesPerGallon: 30, cylinders: 4, horsepower: 76 }, + { name: 'toyota corolla 1200', milesPerGallon: 31, cylinders: 4, horsepower: 65 }, + { name: 'datsun 1200', milesPerGallon: 35, cylinders: 4, horsepower: 69 }, + { name: 'volkswagen model 111', milesPerGallon: 27, cylinders: 4, horsepower: 60 }, + { name: 'plymouth cricket', milesPerGallon: 26, cylinders: 4, horsepower: 70 }, + { name: 'toyota corona hardtop', milesPerGallon: 24, cylinders: 4, horsepower: 95 }, + { name: 'dodge colt hardtop', milesPerGallon: 25, cylinders: 4, horsepower: 80 }, + { name: 'volkswagen type 3', milesPerGallon: 23, cylinders: 4, horsepower: 54 }, + { name: 'chevrolet vega', milesPerGallon: 20, cylinders: 4, horsepower: 90 }, + { name: 'ford pinto runabout', milesPerGallon: 21, cylinders: 4, horsepower: 86 }, + { name: 'chevrolet impala', milesPerGallon: 13, cylinders: 8, horsepower: 165 }, + { name: 'pontiac catalina', milesPerGallon: 14, cylinders: 8, horsepower: 175 }, + { name: 'plymouth fury iii', milesPerGallon: 15, cylinders: 8, horsepower: 150 }, + { name: 'ford galaxie 500', milesPerGallon: 14, cylinders: 8, horsepower: 153 }, + { name: 'amc ambassador sst', milesPerGallon: 17, cylinders: 8, horsepower: 150 }, + { name: 'mercury marquis', milesPerGallon: 11, cylinders: 8, horsepower: 208 }, + { name: 'buick lesabre custom', milesPerGallon: 13, cylinders: 8, horsepower: 155 }, + { name: 'oldsmobile delta 88 royale', milesPerGallon: 12, cylinders: 8, horsepower: 160 }, + { name: 'chrysler newport royal', milesPerGallon: 13, cylinders: 8, horsepower: 190 }, + { name: 'mazda rx2 coupe', milesPerGallon: 19, cylinders: 3, horsepower: 97 }, + { name: 'amc matador (sw)', milesPerGallon: 15, cylinders: 8, horsepower: 150 }, + { name: 'chevrolet chevelle concours (sw)', milesPerGallon: 13, cylinders: 8, horsepower: 130 }, + { name: 'ford gran torino (sw)', milesPerGallon: 13, cylinders: 8, horsepower: 140 }, + { name: 'plymouth satellite custom (sw)', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'volvo 145e (sw)', milesPerGallon: 18, cylinders: 4, horsepower: 112 }, + { name: 'volkswagen 411 (sw)', milesPerGallon: 22, cylinders: 4, horsepower: 76 }, + { name: 'peugeot 504 (sw)', milesPerGallon: 21, cylinders: 4, horsepower: 87 }, + { name: 'renault 12 (sw)', milesPerGallon: 26, cylinders: 4, horsepower: 69 }, + { name: 'ford pinto (sw)', milesPerGallon: 22, cylinders: 4, horsepower: 86 }, + { name: 'datsun 510 (sw)', milesPerGallon: 28, cylinders: 4, horsepower: 92 }, + { name: 'toyouta corona mark ii (sw)', milesPerGallon: 23, cylinders: 4, horsepower: 97 }, + { name: 'dodge colt (sw)', milesPerGallon: 28, cylinders: 4, horsepower: 80 }, + { name: 'toyota corolla 1600 (sw)', milesPerGallon: 27, cylinders: 4, horsepower: 88 }, + { name: 'buick century 350', milesPerGallon: 13, cylinders: 8, horsepower: 175 }, + { name: 'amc matador', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'chevrolet malibu', milesPerGallon: 13, cylinders: 8, horsepower: 145 }, + { name: 'ford gran torino', milesPerGallon: 14, cylinders: 8, horsepower: 137 }, + { name: 'dodge coronet custom', milesPerGallon: 15, cylinders: 8, horsepower: 150 }, + { name: 'mercury marquis brougham', milesPerGallon: 12, cylinders: 8, horsepower: 198 }, + { name: 'chevrolet caprice classic', milesPerGallon: 13, cylinders: 8, horsepower: 150 }, + { name: 'ford ltd', milesPerGallon: 13, cylinders: 8, horsepower: 158 }, + { name: 'plymouth fury gran sedan', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'chrysler new yorker brougham', milesPerGallon: 13, cylinders: 8, horsepower: 215 }, + { name: 'buick electra 225 custom', milesPerGallon: 12, cylinders: 8, horsepower: 225 }, + { name: 'amc ambassador brougham', milesPerGallon: 13, cylinders: 8, horsepower: 175 }, + { name: 'plymouth valiant', milesPerGallon: 18, cylinders: 6, horsepower: 105 }, + { name: 'chevrolet nova custom', milesPerGallon: 16, cylinders: 6, horsepower: 100 }, + { name: 'amc hornet', milesPerGallon: 18, cylinders: 6, horsepower: 100 }, + { name: 'ford maverick', milesPerGallon: 18, cylinders: 6, horsepower: 88 }, + { name: 'plymouth duster', milesPerGallon: 23, cylinders: 6, horsepower: 95 }, + { name: 'volkswagen super beetle', milesPerGallon: 26, cylinders: 4, horsepower: 46 }, + { name: 'chevrolet impala', milesPerGallon: 11, cylinders: 8, horsepower: 150 }, + { name: 'ford country', milesPerGallon: 12, cylinders: 8, horsepower: 167 }, + { name: 'plymouth custom suburb', milesPerGallon: 13, cylinders: 8, horsepower: 170 }, + { name: 'oldsmobile vista cruiser', milesPerGallon: 12, cylinders: 8, horsepower: 180 }, + { name: 'amc gremlin', milesPerGallon: 18, cylinders: 6, horsepower: 100 }, + { name: 'toyota carina', milesPerGallon: 20, cylinders: 4, horsepower: 88 }, + { name: 'chevrolet vega', milesPerGallon: 21, cylinders: 4, horsepower: 72 }, + { name: 'datsun 610', milesPerGallon: 22, cylinders: 4, horsepower: 94 }, + { name: 'maxda rx3', milesPerGallon: 18, cylinders: 3, horsepower: 90 }, + { name: 'ford pinto', milesPerGallon: 19, cylinders: 4, horsepower: 85 }, + { name: 'mercury capri v6', milesPerGallon: 21, cylinders: 6, horsepower: 107 }, + { name: 'fiat 124 sport coupe', milesPerGallon: 26, cylinders: 4, horsepower: 90 }, + { name: 'chevrolet monte carlo s', milesPerGallon: 15, cylinders: 8, horsepower: 145 }, + { name: 'pontiac grand prix', milesPerGallon: 16, cylinders: 8, horsepower: 230 }, + { name: 'fiat 128', milesPerGallon: 29, cylinders: 4, horsepower: 49 }, + { name: 'opel manta', milesPerGallon: 24, cylinders: 4, horsepower: 75 }, + { name: 'audi 100ls', milesPerGallon: 20, cylinders: 4, horsepower: 91 }, + { name: 'volvo 144ea', milesPerGallon: 19, cylinders: 4, horsepower: 112 }, + { name: 'dodge dart custom', milesPerGallon: 15, cylinders: 8, horsepower: 150 }, + { name: 'saab 99le', milesPerGallon: 24, cylinders: 4, horsepower: 110 }, + { name: 'toyota mark ii', milesPerGallon: 20, cylinders: 6, horsepower: 122 }, + { name: 'oldsmobile omega', milesPerGallon: 11, cylinders: 8, horsepower: 180 }, + { name: 'plymouth duster', milesPerGallon: 20, cylinders: 6, horsepower: 95 }, + { name: 'ford maverick', milesPerGallon: 21, cylinders: 6, horsepower: 0 }, + { name: 'amc hornet', milesPerGallon: 19, cylinders: 6, horsepower: 100 }, + { name: 'chevrolet nova', milesPerGallon: 15, cylinders: 6, horsepower: 100 }, + { name: 'datsun b210', milesPerGallon: 31, cylinders: 4, horsepower: 67 }, + { name: 'ford pinto', milesPerGallon: 26, cylinders: 4, horsepower: 80 }, + { name: 'toyota corolla 1200', milesPerGallon: 32, cylinders: 4, horsepower: 65 }, + { name: 'chevrolet vega', milesPerGallon: 25, cylinders: 4, horsepower: 75 }, + { name: 'chevrolet chevelle malibu classic', milesPerGallon: 16, cylinders: 6, horsepower: 100 }, + { name: 'amc matador', milesPerGallon: 16, cylinders: 6, horsepower: 110 }, + { name: 'plymouth satellite sebring', milesPerGallon: 18, cylinders: 6, horsepower: 105 }, + { name: 'ford gran torino', milesPerGallon: 16, cylinders: 8, horsepower: 140 }, + { name: 'buick century luxus (sw)', milesPerGallon: 13, cylinders: 8, horsepower: 150 }, + { name: 'dodge coronet custom (sw)', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'ford gran torino (sw)', milesPerGallon: 14, cylinders: 8, horsepower: 140 }, + { name: 'amc matador (sw)', milesPerGallon: 14, cylinders: 8, horsepower: 150 }, + { name: 'audi fox', milesPerGallon: 29, cylinders: 4, horsepower: 83 }, + { name: 'volkswagen dasher', milesPerGallon: 26, cylinders: 4, horsepower: 67 }, + { name: 'opel manta', milesPerGallon: 26, cylinders: 4, horsepower: 78 }, + { name: 'toyota corona', milesPerGallon: 31, cylinders: 4, horsepower: 52 }, + { name: 'datsun 710', milesPerGallon: 32, cylinders: 4, horsepower: 61 }, + { name: 'dodge colt', milesPerGallon: 28, cylinders: 4, horsepower: 75 }, + { name: 'fiat 128', milesPerGallon: 24, cylinders: 4, horsepower: 75 }, + { name: 'fiat 124 tc', milesPerGallon: 26, cylinders: 4, horsepower: 75 }, + { name: 'honda civic', milesPerGallon: 24, cylinders: 4, horsepower: 97 }, + { name: 'subaru', milesPerGallon: 26, cylinders: 4, horsepower: 93 }, + { name: 'fiat x1.9', milesPerGallon: 31, cylinders: 4, horsepower: 67 }, + { name: 'plymouth valiant custom', milesPerGallon: 19, cylinders: 6, horsepower: 95 }, + { name: 'chevrolet nova', milesPerGallon: 18, cylinders: 6, horsepower: 105 }, + { name: 'mercury monarch', milesPerGallon: 15, cylinders: 6, horsepower: 72 }, + { name: 'ford maverick', milesPerGallon: 15, cylinders: 6, horsepower: 72 }, + { name: 'pontiac catalina', milesPerGallon: 16, cylinders: 8, horsepower: 170 }, + { name: 'chevrolet bel air', milesPerGallon: 15, cylinders: 8, horsepower: 145 }, + { name: 'plymouth grand fury', milesPerGallon: 16, cylinders: 8, horsepower: 150 }, + { name: 'ford ltd', milesPerGallon: 14, cylinders: 8, horsepower: 148 }, + { name: 'buick century', milesPerGallon: 17, cylinders: 6, horsepower: 110 }, + { name: 'chevroelt chevelle malibu', milesPerGallon: 16, cylinders: 6, horsepower: 105 }, + { name: 'amc matador', milesPerGallon: 15, cylinders: 6, horsepower: 110 }, + { name: 'plymouth fury', milesPerGallon: 18, cylinders: 6, horsepower: 95 }, + { name: 'buick skyhawk', milesPerGallon: 21, cylinders: 6, horsepower: 110 }, + { name: 'chevrolet monza 2+2', milesPerGallon: 20, cylinders: 8, horsepower: 110 }, + { name: 'ford mustang ii', milesPerGallon: 13, cylinders: 8, horsepower: 129 }, + { name: 'toyota corolla', milesPerGallon: 29, cylinders: 4, horsepower: 75 }, + { name: 'ford pinto', milesPerGallon: 23, cylinders: 4, horsepower: 83 }, + { name: 'amc gremlin', milesPerGallon: 20, cylinders: 6, horsepower: 100 }, + { name: 'pontiac astro', milesPerGallon: 23, cylinders: 4, horsepower: 78 }, + { name: 'toyota corona', milesPerGallon: 24, cylinders: 4, horsepower: 96 }, + { name: 'volkswagen dasher', milesPerGallon: 25, cylinders: 4, horsepower: 71 }, + { name: 'datsun 710', milesPerGallon: 24, cylinders: 4, horsepower: 97 }, + { name: 'ford pinto', milesPerGallon: 18, cylinders: 6, horsepower: 97 }, + { name: 'volkswagen rabbit', milesPerGallon: 29, cylinders: 4, horsepower: 70 }, + { name: 'amc pacer', milesPerGallon: 19, cylinders: 6, horsepower: 90 }, + { name: 'audi 100ls', milesPerGallon: 23, cylinders: 4, horsepower: 95 }, + { name: 'peugeot 504', milesPerGallon: 23, cylinders: 4, horsepower: 88 }, + { name: 'volvo 244dl', milesPerGallon: 22, cylinders: 4, horsepower: 98 }, + { name: 'saab 99le', milesPerGallon: 25, cylinders: 4, horsepower: 115 }, + { name: 'honda civic cvcc', milesPerGallon: 33, cylinders: 4, horsepower: 53 }, + { name: 'fiat 131', milesPerGallon: 28, cylinders: 4, horsepower: 86 }, + { name: 'opel 1900', milesPerGallon: 25, cylinders: 4, horsepower: 81 }, + { name: 'capri ii', milesPerGallon: 25, cylinders: 4, horsepower: 92 }, + { name: 'dodge colt', milesPerGallon: 26, cylinders: 4, horsepower: 79 }, + { name: 'renault 12tl', milesPerGallon: 27, cylinders: 4, horsepower: 83 }, + { name: 'chevrolet chevelle malibu classic', milesPerGallon: 17.5, cylinders: 8, horsepower: 140 }, + { name: 'dodge coronet brougham', milesPerGallon: 16, cylinders: 8, horsepower: 150 }, + { name: 'amc matador', milesPerGallon: 15.5, cylinders: 8, horsepower: 120 }, + { name: 'ford gran torino', milesPerGallon: 14.5, cylinders: 8, horsepower: 152 }, + { name: 'plymouth valiant', milesPerGallon: 22, cylinders: 6, horsepower: 100 }, + { name: 'chevrolet nova', milesPerGallon: 22, cylinders: 6, horsepower: 105 }, + { name: 'ford maverick', milesPerGallon: 24, cylinders: 6, horsepower: 81 }, + { name: 'amc hornet', milesPerGallon: 22.5, cylinders: 6, horsepower: 90 }, + { name: 'chevrolet chevette', milesPerGallon: 29, cylinders: 4, horsepower: 52 }, + { name: 'chevrolet woody', milesPerGallon: 24.5, cylinders: 4, horsepower: 60 }, + { name: 'vw rabbit', milesPerGallon: 29, cylinders: 4, horsepower: 70 }, + { name: 'honda civic', milesPerGallon: 33, cylinders: 4, horsepower: 53 }, + { name: 'dodge aspen se', milesPerGallon: 20, cylinders: 6, horsepower: 100 }, + { name: 'ford granada ghia', milesPerGallon: 18, cylinders: 6, horsepower: 78 }, + { name: 'pontiac ventura sj', milesPerGallon: 18.5, cylinders: 6, horsepower: 110 }, + { name: 'amc pacer d/l', milesPerGallon: 17.5, cylinders: 6, horsepower: 95 }, + { name: 'volkswagen rabbit', milesPerGallon: 29.5, cylinders: 4, horsepower: 71 }, + { name: 'datsun b-210', milesPerGallon: 32, cylinders: 4, horsepower: 70 }, + { name: 'toyota corolla', milesPerGallon: 28, cylinders: 4, horsepower: 75 }, + { name: 'ford pinto', milesPerGallon: 26.5, cylinders: 4, horsepower: 72 }, + { name: 'volvo 245', milesPerGallon: 20, cylinders: 4, horsepower: 102 }, + { name: 'plymouth volare premier v8', milesPerGallon: 13, cylinders: 8, horsepower: 150 }, + { name: 'peugeot 504', milesPerGallon: 19, cylinders: 4, horsepower: 88 }, + { name: 'toyota mark ii', milesPerGallon: 19, cylinders: 6, horsepower: 108 }, + { name: 'mercedes-benz 280s', milesPerGallon: 16.5, cylinders: 6, horsepower: 120 }, + { name: 'cadillac seville', milesPerGallon: 16.5, cylinders: 8, horsepower: 180 }, + { name: 'chevy c10', milesPerGallon: 13, cylinders: 8, horsepower: 145 }, + { name: 'ford f108', milesPerGallon: 13, cylinders: 8, horsepower: 130 }, + { name: 'dodge d100', milesPerGallon: 13, cylinders: 8, horsepower: 150 }, + { name: 'honda Accelerationord cvcc', milesPerGallon: 31.5, cylinders: 4, horsepower: 68 }, + { name: 'buick opel isuzu deluxe', milesPerGallon: 30, cylinders: 4, horsepower: 80 }, + { name: 'renault 5 gtl', milesPerGallon: 36, cylinders: 4, horsepower: 58 }, + { name: 'plymouth arrow gs', milesPerGallon: 25.5, cylinders: 4, horsepower: 96 }, + { name: 'datsun f-10 hatchback', milesPerGallon: 33.5, cylinders: 4, horsepower: 70 }, + { name: 'chevrolet caprice classic', milesPerGallon: 17.5, cylinders: 8, horsepower: 145 }, + { name: 'oldsmobile cutlass supreme', milesPerGallon: 17, cylinders: 8, horsepower: 110 }, + { name: 'dodge monaco brougham', milesPerGallon: 15.5, cylinders: 8, horsepower: 145 }, + { name: 'mercury cougar brougham', milesPerGallon: 15, cylinders: 8, horsepower: 130 }, + { name: 'chevrolet concours', milesPerGallon: 17.5, cylinders: 6, horsepower: 110 }, + { name: 'buick skylark', milesPerGallon: 20.5, cylinders: 6, horsepower: 105 }, + { name: 'plymouth volare custom', milesPerGallon: 19, cylinders: 6, horsepower: 100 }, + { name: 'ford granada', milesPerGallon: 18.5, cylinders: 6, horsepower: 98 }, + { name: 'pontiac grand prix lj', milesPerGallon: 16, cylinders: 8, horsepower: 180 }, + { name: 'chevrolet monte carlo landau', milesPerGallon: 15.5, cylinders: 8, horsepower: 170 }, + { name: 'chrysler cordoba', milesPerGallon: 15.5, cylinders: 8, horsepower: 190 }, + { name: 'ford thunderbird', milesPerGallon: 16, cylinders: 8, horsepower: 149 }, + { name: 'volkswagen rabbit custom', milesPerGallon: 29, cylinders: 4, horsepower: 78 }, + { name: 'pontiac sunbird coupe', milesPerGallon: 24.5, cylinders: 4, horsepower: 88 }, + { name: 'toyota corolla liftback', milesPerGallon: 26, cylinders: 4, horsepower: 75 }, + { name: 'ford mustang ii 2+2', milesPerGallon: 25.5, cylinders: 4, horsepower: 89 }, + { name: 'chevrolet chevette', milesPerGallon: 30.5, cylinders: 4, horsepower: 63 }, + { name: 'dodge colt m/m', milesPerGallon: 33.5, cylinders: 4, horsepower: 83 }, + { name: 'subaru dl', milesPerGallon: 30, cylinders: 4, horsepower: 67 }, + { name: 'volkswagen dasher', milesPerGallon: 30.5, cylinders: 4, horsepower: 78 }, + { name: 'datsun 810', milesPerGallon: 22, cylinders: 6, horsepower: 97 }, + { name: 'bmw 320i', milesPerGallon: 21.5, cylinders: 4, horsepower: 110 }, + { name: 'mazda rx-4', milesPerGallon: 21.5, cylinders: 3, horsepower: 110 }, + { name: 'volkswagen rabbit custom diesel', milesPerGallon: 43.1, cylinders: 4, horsepower: 48 }, + { name: 'ford fiesta', milesPerGallon: 36.1, cylinders: 4, horsepower: 66 }, + { name: 'mazda glc deluxe', milesPerGallon: 32.8, cylinders: 4, horsepower: 52 }, + { name: 'datsun b210 gx', milesPerGallon: 39.4, cylinders: 4, horsepower: 70 }, + { name: 'honda civic cvcc', milesPerGallon: 36.1, cylinders: 4, horsepower: 60 }, + { name: 'oldsmobile cutlass salon brougham', milesPerGallon: 19.9, cylinders: 8, horsepower: 110 }, + { name: 'dodge diplomat', milesPerGallon: 19.4, cylinders: 8, horsepower: 140 }, + { name: 'mercury monarch ghia', milesPerGallon: 20.2, cylinders: 8, horsepower: 139 }, + { name: 'pontiac phoenix lj', milesPerGallon: 19.2, cylinders: 6, horsepower: 105 }, + { name: 'chevrolet malibu', milesPerGallon: 20.5, cylinders: 6, horsepower: 95 }, + { name: 'ford fairmont (auto)', milesPerGallon: 20.2, cylinders: 6, horsepower: 85 }, + { name: 'ford fairmont (man)', milesPerGallon: 25.1, cylinders: 4, horsepower: 88 }, + { name: 'plymouth volare', milesPerGallon: 20.5, cylinders: 6, horsepower: 100 }, + { name: 'amc concord', milesPerGallon: 19.4, cylinders: 6, horsepower: 90 }, + { name: 'buick century special', milesPerGallon: 20.6, cylinders: 6, horsepower: 105 }, + { name: 'mercury zephyr', milesPerGallon: 20.8, cylinders: 6, horsepower: 85 }, + { name: 'dodge aspen', milesPerGallon: 18.6, cylinders: 6, horsepower: 110 }, + { name: 'amc concord d/l', milesPerGallon: 18.1, cylinders: 6, horsepower: 120 }, + { name: 'chevrolet monte carlo landau', milesPerGallon: 19.2, cylinders: 8, horsepower: 145 }, + { name: 'buick regal sport coupe (turbo)', milesPerGallon: 17.7, cylinders: 6, horsepower: 165 }, + { name: 'ford futura', milesPerGallon: 18.1, cylinders: 8, horsepower: 139 }, + { name: 'dodge magnum xe', milesPerGallon: 17.5, cylinders: 8, horsepower: 140 }, + { name: 'chevrolet chevette', milesPerGallon: 30, cylinders: 4, horsepower: 68 }, + { name: 'toyota corona', milesPerGallon: 27.5, cylinders: 4, horsepower: 95 }, + { name: 'datsun 510', milesPerGallon: 27.2, cylinders: 4, horsepower: 97 }, + { name: 'dodge omni', milesPerGallon: 30.9, cylinders: 4, horsepower: 75 }, + { name: 'toyota celica gt liftback', milesPerGallon: 21.1, cylinders: 4, horsepower: 95 }, + { name: 'plymouth sapporo', milesPerGallon: 23.2, cylinders: 4, horsepower: 105 }, + { name: 'oldsmobile starfire sx', milesPerGallon: 23.8, cylinders: 4, horsepower: 85 }, + { name: 'datsun 200-sx', milesPerGallon: 23.9, cylinders: 4, horsepower: 97 }, + { name: 'audi 5000', milesPerGallon: 20.3, cylinders: 5, horsepower: 103 }, + { name: 'volvo 264gl', milesPerGallon: 17, cylinders: 6, horsepower: 125 }, + { name: 'saab 99gle', milesPerGallon: 21.6, cylinders: 4, horsepower: 115 }, + { name: 'peugeot 604sl', milesPerGallon: 16.2, cylinders: 6, horsepower: 133 }, + { name: 'volkswagen scirocco', milesPerGallon: 31.5, cylinders: 4, horsepower: 71 }, + { name: 'honda Accelerationord lx', milesPerGallon: 29.5, cylinders: 4, horsepower: 68 }, + { name: 'pontiac lemans v6', milesPerGallon: 21.5, cylinders: 6, horsepower: 115 }, + { name: 'mercury zephyr 6', milesPerGallon: 19.8, cylinders: 6, horsepower: 85 }, + { name: 'ford fairmont 4', milesPerGallon: 22.3, cylinders: 4, horsepower: 88 }, + { name: 'amc concord dl 6', milesPerGallon: 20.2, cylinders: 6, horsepower: 90 }, + { name: 'dodge aspen 6', milesPerGallon: 20.6, cylinders: 6, horsepower: 110 }, + { name: 'chevrolet caprice classic', milesPerGallon: 17, cylinders: 8, horsepower: 130 }, + { name: 'ford ltd landau', milesPerGallon: 17.6, cylinders: 8, horsepower: 129 }, + { name: 'mercury grand marquis', milesPerGallon: 16.5, cylinders: 8, horsepower: 138 }, + { name: 'dodge st. regis', milesPerGallon: 18.2, cylinders: 8, horsepower: 135 }, + { name: 'buick estate wagon (sw)', milesPerGallon: 16.9, cylinders: 8, horsepower: 155 }, + { name: 'ford country squire (sw)', milesPerGallon: 15.5, cylinders: 8, horsepower: 142 }, + { name: 'chevrolet malibu classic (sw)', milesPerGallon: 19.2, cylinders: 8, horsepower: 125 }, + { name: 'chrysler lebaron town @ country (sw)', milesPerGallon: 18.5, cylinders: 8, horsepower: 150 }, + { name: 'vw rabbit custom', milesPerGallon: 31.9, cylinders: 4, horsepower: 71 }, + { name: 'maxda glc deluxe', milesPerGallon: 34.1, cylinders: 4, horsepower: 65 }, + { name: 'dodge colt hatchback custom', milesPerGallon: 35.7, cylinders: 4, horsepower: 80 }, + { name: 'amc spirit dl', milesPerGallon: 27.4, cylinders: 4, horsepower: 80 }, + { name: 'mercedes benz 300d', milesPerGallon: 25.4, cylinders: 5, horsepower: 77 }, + { name: 'cadillac eldorado', milesPerGallon: 23, cylinders: 8, horsepower: 125 }, + { name: 'peugeot 504', milesPerGallon: 27.2, cylinders: 4, horsepower: 71 }, + { name: 'oldsmobile cutlass salon brougham', milesPerGallon: 23.9, cylinders: 8, horsepower: 90 }, + { name: 'plymouth horizon', milesPerGallon: 34.2, cylinders: 4, horsepower: 70 }, + { name: 'plymouth horizon tc3', milesPerGallon: 34.5, cylinders: 4, horsepower: 70 }, + { name: 'datsun 210', milesPerGallon: 31.8, cylinders: 4, horsepower: 65 }, + { name: 'fiat strada custom', milesPerGallon: 37.3, cylinders: 4, horsepower: 69 }, + { name: 'buick skylark limited', milesPerGallon: 28.4, cylinders: 4, horsepower: 90 }, + { name: 'chevrolet citation', milesPerGallon: 28.8, cylinders: 6, horsepower: 115 }, + { name: 'oldsmobile omega brougham', milesPerGallon: 26.8, cylinders: 6, horsepower: 115 }, + { name: 'pontiac phoenix', milesPerGallon: 33.5, cylinders: 4, horsepower: 90 }, + { name: 'vw rabbit', milesPerGallon: 41.5, cylinders: 4, horsepower: 76 }, + { name: 'toyota corolla tercel', milesPerGallon: 38.1, cylinders: 4, horsepower: 60 }, + { name: 'chevrolet chevette', milesPerGallon: 32.1, cylinders: 4, horsepower: 70 }, + { name: 'datsun 310', milesPerGallon: 37.2, cylinders: 4, horsepower: 65 }, + { name: 'chevrolet citation', milesPerGallon: 28, cylinders: 4, horsepower: 90 }, + { name: 'ford fairmont', milesPerGallon: 26.4, cylinders: 4, horsepower: 88 }, + { name: 'amc concord', milesPerGallon: 24.3, cylinders: 4, horsepower: 90 }, + { name: 'dodge aspen', milesPerGallon: 19.1, cylinders: 6, horsepower: 90 }, + { name: 'audi 4000', milesPerGallon: 34.3, cylinders: 4, horsepower: 78 }, + { name: 'toyota corona liftback', milesPerGallon: 29.8, cylinders: 4, horsepower: 90 }, + { name: 'mazda 626', milesPerGallon: 31.3, cylinders: 4, horsepower: 75 }, + { name: 'datsun 510 hatchback', milesPerGallon: 37, cylinders: 4, horsepower: 92 }, + { name: 'toyota corolla', milesPerGallon: 32.2, cylinders: 4, horsepower: 75 }, + { name: 'mazda glc', milesPerGallon: 46.6, cylinders: 4, horsepower: 65 }, + { name: 'dodge colt', milesPerGallon: 27.9, cylinders: 4, horsepower: 105 }, + { name: 'datsun 210', milesPerGallon: 40.8, cylinders: 4, horsepower: 65 }, + { name: 'vw rabbit c (diesel)', milesPerGallon: 44.3, cylinders: 4, horsepower: 48 }, + { name: 'vw dasher (diesel)', milesPerGallon: 43.4, cylinders: 4, horsepower: 48 }, + { name: 'audi 5000s (diesel)', milesPerGallon: 36.4, cylinders: 5, horsepower: 67 }, + { name: 'mercedes-benz 240d', milesPerGallon: 30, cylinders: 4, horsepower: 67 }, + { name: 'honda civic 1500 gl', milesPerGallon: 44.6, cylinders: 4, horsepower: 67 }, + { name: 'renault lecar deluxe', milesPerGallon: 40.9, cylinders: 4, horsepower: 0 }, + { name: 'subaru dl', milesPerGallon: 33.8, cylinders: 4, horsepower: 67 }, + { name: 'vokswagen rabbit', milesPerGallon: 29.8, cylinders: 4, horsepower: 62 }, + { name: 'datsun 280-zx', milesPerGallon: 32.7, cylinders: 6, horsepower: 132 }, + { name: 'mazda rx-7 gs', milesPerGallon: 23.7, cylinders: 3, horsepower: 100 }, + { name: 'triumph tr7 coupe', milesPerGallon: 35, cylinders: 4, horsepower: 88 }, + { name: 'ford mustang cobra', milesPerGallon: 23.6, cylinders: 4, horsepower: 0 }, + { name: 'honda Accelerationord', milesPerGallon: 32.4, cylinders: 4, horsepower: 72 }, + { name: 'plymouth reliant', milesPerGallon: 27.2, cylinders: 4, horsepower: 84 }, + { name: 'buick skylark', milesPerGallon: 26.6, cylinders: 4, horsepower: 84 }, + { name: 'dodge aries wagon (sw)', milesPerGallon: 25.8, cylinders: 4, horsepower: 92 }, + { name: 'chevrolet citation', milesPerGallon: 23.5, cylinders: 6, horsepower: 110 }, + { name: 'plymouth reliant', milesPerGallon: 30, cylinders: 4, horsepower: 84 }, + { name: 'toyota starlet', milesPerGallon: 39.1, cylinders: 4, horsepower: 58 }, + { name: 'plymouth champ', milesPerGallon: 39, cylinders: 4, horsepower: 64 }, + { name: 'honda civic 1300', milesPerGallon: 35.1, cylinders: 4, horsepower: 60 }, + { name: 'subaru', milesPerGallon: 32.3, cylinders: 4, horsepower: 67 }, + { name: 'datsun 210', milesPerGallon: 37, cylinders: 4, horsepower: 65 }, + { name: 'toyota tercel', milesPerGallon: 37.7, cylinders: 4, horsepower: 62 }, + { name: 'mazda glc 4', milesPerGallon: 34.1, cylinders: 4, horsepower: 68 }, + { name: 'plymouth horizon 4', milesPerGallon: 34.7, cylinders: 4, horsepower: 63 }, + { name: 'ford escort 4w', milesPerGallon: 34.4, cylinders: 4, horsepower: 65 }, + { name: 'ford escort 2h', milesPerGallon: 29.9, cylinders: 4, horsepower: 65 }, + { name: 'volkswagen jetta', milesPerGallon: 33, cylinders: 4, horsepower: 74 }, + { name: 'renault 18i', milesPerGallon: 34.5, cylinders: 4, horsepower: 0 }, + { name: 'honda prelude', milesPerGallon: 33.7, cylinders: 4, horsepower: 75 }, + { name: 'toyota corolla', milesPerGallon: 32.4, cylinders: 4, horsepower: 75 }, + { name: 'datsun 200sx', milesPerGallon: 32.9, cylinders: 4, horsepower: 100 }, + { name: 'mazda 626', milesPerGallon: 31.6, cylinders: 4, horsepower: 74 }, + { name: 'peugeot 505s turbo diesel', milesPerGallon: 28.1, cylinders: 4, horsepower: 80 }, + { name: 'saab 900s', milesPerGallon: 0, cylinders: 4, horsepower: 110 }, + { name: 'volvo diesel', milesPerGallon: 30.7, cylinders: 6, horsepower: 76 }, + { name: 'toyota cressida', milesPerGallon: 25.4, cylinders: 6, horsepower: 116 }, + { name: 'datsun 810 maxima', milesPerGallon: 24.2, cylinders: 6, horsepower: 120 }, + { name: 'buick century', milesPerGallon: 22.4, cylinders: 6, horsepower: 110 }, + { name: 'oldsmobile cutlass ls', milesPerGallon: 26.6, cylinders: 8, horsepower: 105 }, + { name: 'ford granada gl', milesPerGallon: 20.2, cylinders: 6, horsepower: 88 }, + { name: 'chrysler lebaron salon', milesPerGallon: 17.6, cylinders: 6, horsepower: 85 }, + { name: 'chevrolet cavalier', milesPerGallon: 28, cylinders: 4, horsepower: 88 }, + { name: 'chevrolet cavalier wagon', milesPerGallon: 27, cylinders: 4, horsepower: 88 }, + { name: 'chevrolet cavalier 2-door', milesPerGallon: 34, cylinders: 4, horsepower: 88 }, + { name: 'pontiac j2000 se hatchback', milesPerGallon: 31, cylinders: 4, horsepower: 85 }, + { name: 'dodge aries se', milesPerGallon: 29, cylinders: 4, horsepower: 84 }, + { name: 'pontiac phoenix', milesPerGallon: 27, cylinders: 4, horsepower: 90 }, + { name: 'ford fairmont futura', milesPerGallon: 24, cylinders: 4, horsepower: 92 }, + { name: 'amc concord dl', milesPerGallon: 23, cylinders: 4, horsepower: 0 }, + { name: 'volkswagen rabbit l', milesPerGallon: 36, cylinders: 4, horsepower: 74 }, + { name: 'mazda glc custom l', milesPerGallon: 37, cylinders: 4, horsepower: 68 }, + { name: 'mazda glc custom', milesPerGallon: 31, cylinders: 4, horsepower: 68 }, + { name: 'plymouth horizon miser', milesPerGallon: 38, cylinders: 4, horsepower: 63 }, + { name: 'mercury lynx l', milesPerGallon: 36, cylinders: 4, horsepower: 70 }, + { name: 'nissan stanza xe', milesPerGallon: 36, cylinders: 4, horsepower: 88 }, + { name: 'honda Accelerationord', milesPerGallon: 36, cylinders: 4, horsepower: 75 }, + { name: 'toyota corolla', milesPerGallon: 34, cylinders: 4, horsepower: 70 }, + { name: 'honda civic', milesPerGallon: 38, cylinders: 4, horsepower: 67 }, + { name: 'honda civic (auto)', milesPerGallon: 32, cylinders: 4, horsepower: 67 }, + { name: 'datsun 310 gx', milesPerGallon: 38, cylinders: 4, horsepower: 67 }, + { name: 'buick century limited', milesPerGallon: 25, cylinders: 6, horsepower: 110 }, + { name: 'oldsmobile cutlass ciera (diesel)', milesPerGallon: 38, cylinders: 6, horsepower: 85 }, + { name: 'chrysler lebaron medallion', milesPerGallon: 26, cylinders: 4, horsepower: 92 }, + { name: 'ford granada l', milesPerGallon: 22, cylinders: 6, horsepower: 112 }, + { name: 'toyota celica gt', milesPerGallon: 32, cylinders: 4, horsepower: 96 }, + { name: 'dodge charger 2.2', milesPerGallon: 36, cylinders: 4, horsepower: 84 }, + { name: 'chevrolet camaro', milesPerGallon: 27, cylinders: 4, horsepower: 90 }, + { name: 'ford mustang gl', milesPerGallon: 27, cylinders: 4, horsepower: 86 }, + { name: 'vw pickup', milesPerGallon: 44, cylinders: 4, horsepower: 52 }, + { name: 'dodge rampage', milesPerGallon: 32, cylinders: 4, horsepower: 84 }, + { name: 'ford ranger', milesPerGallon: 28, cylinders: 4, horsepower: 79 }, + { name: 'chevy s-10', milesPerGallon: 31, cylinders: 4, horsepower: 82 } +].filter(entry => { + const delta = entry.horsepower - entry.milesPerGallon; + return delta > 100 || delta < 20; +}); + +// 图表配置 +const spec = { + type: 'common', + series: [ + { + type: 'scatter', + xField: 'milesPerGallon', + yField: 'horsepower', + point: { + state: { + hover: { + scaleX: 1.2, + scaleY: 1.2 + } + }, + style: { + fillOpacity: 0.25 + } + } + } + ], + tooltip: { + dimension: { + visible: true + }, + mark: { + title: true, + content: [ + { + key: d => d.name, + value: d => d.y + } + ] + } + }, + crosshair: { + yField: { + visible: true, + line: { + visible: true, + type: 'line' + }, + label: { + visible: true // label 默认关闭 + } + }, + xField: { + visible: true, + line: { + visible: true, + type: 'line' + }, + label: { + visible: true // label 默认关闭 + } + } + }, + axes: [ + { + title: { + visible: true, + text: 'Horse Power' + }, + orient: 'left', + range: { min: 0 }, + type: 'linear' + }, + { + title: { + visible: true, + text: 'Miles Per Gallon' + }, + orient: 'bottom', + label: { visible: true }, + type: 'linear' + } + ], + data: [ + { + id: 'data', + values: data.flat() + } + ] +}; + +const run = () => { + registerRegressionLine(); + appendScatterRegressionLineConfig(spec, [ + { + type: 'logisitc', + color: 'red', + label: { + text: 'logisitc' + } + } + ]); + + const cs = new VChart(spec, { + dom: document.getElementById('chart') as HTMLElement, + //theme: 'dark', + onError: err => { + console.error(err); + } + }); + + cs.renderSync(); + + window['vchart'] = cs; +}; +run(); diff --git a/packages/vchart-extension/src/components/bar-regression-line/index.ts b/packages/vchart-extension/src/components/bar-regression-line/index.ts index fb9ecc4d5e..c95b4a0e67 100644 --- a/packages/vchart-extension/src/components/bar-regression-line/index.ts +++ b/packages/vchart-extension/src/components/bar-regression-line/index.ts @@ -55,6 +55,7 @@ export function getBarRegressionLineConfig(config: Omit { const d = { [fieldX]: groups[ld.x], [fieldY]: ld.y }; return { @@ -76,7 +77,6 @@ export function getBarRegressionLineConfig(config: Omit> { + extends Partial> { + /** + * 是否显示回归线 + */ visible?: boolean; + /** + * 主色,可以不设置,默认取散点图系列颜色 + */ + color?: string; } diff --git a/packages/vchart-extension/src/components/histogram-regression-line/index.ts b/packages/vchart-extension/src/components/histogram-regression-line/index.ts index 310f2a08b7..ddd7c8adb6 100644 --- a/packages/vchart-extension/src/components/histogram-regression-line/index.ts +++ b/packages/vchart-extension/src/components/histogram-regression-line/index.ts @@ -3,6 +3,7 @@ * @author zhangweixing */ +import type { KDEEvaluator } from '@visactor/vutils'; import { array, get, kde, ecdf, last } from '@visactor/vutils'; import type { Datum, ICartesianSeries, ISpec } from '@visactor/vchart'; import { SeriesTypeEnum } from '@visactor/vchart'; @@ -42,7 +43,7 @@ export function getHistogramRegressionLineConfig( const series = chart.getAllSeries().filter((s: any) => s.type === SeriesTypeEnum.bar) as ICartesianSeries[]; const regressionData: RegressionLineData[] = []; - // 必须存在散点图系列 + // 直方图使用的是bar系列 if (series && series.length) { series.forEach(s => { const region = s.getRegion().getLayoutStartPoint(); @@ -77,13 +78,14 @@ export function getHistogramRegressionLineConfig( const scaleR = type === 'kde' ? (k: number) => { - return scaleY.scale(k * data.length * res.bandwidth); + return scaleY.scale(k * data.length * (res as KDEEvaluator).bandwidth); } : (e: number) => { return y0 + (y1 - y0) * e; }; regressionData.push({ + color: color ?? s.getOption().globalScale.getScale('color')?.scale(s.getSeriesKeys()[0]), line: lineData.map((ld: Datum) => { const d = { [fieldX]: ld.x }; return { @@ -97,7 +99,6 @@ export function getHistogramRegressionLineConfig( return regressionData; }, - color, line, label } diff --git a/packages/vchart-extension/src/components/histogram-regression-line/type.ts b/packages/vchart-extension/src/components/histogram-regression-line/type.ts index a885eee55f..a4e25de7b1 100644 --- a/packages/vchart-extension/src/components/histogram-regression-line/type.ts +++ b/packages/vchart-extension/src/components/histogram-regression-line/type.ts @@ -5,6 +5,13 @@ export interface HistogramRegressionLineAttrs extends Omit> { + extends Partial> { + /** + * 是否显示回归线 + */ visible?: boolean; + /** + * 主色,可以不设置,默认取散点图系列颜色 + */ + color?: string; } diff --git a/packages/vchart-extension/src/components/regression-line/regression-line.ts b/packages/vchart-extension/src/components/regression-line/regression-line.ts index ad7972f026..e4c28ef06e 100644 --- a/packages/vchart-extension/src/components/regression-line/regression-line.ts +++ b/packages/vchart-extension/src/components/regression-line/regression-line.ts @@ -15,14 +15,14 @@ export class RegressionLine extends AbstractComponent { + const { color } = d; if (d.area && confidenceInterval?.visible !== false) { const areaShape = createArea({ points: d.area, diff --git a/packages/vchart-extension/src/components/regression-line/type.ts b/packages/vchart-extension/src/components/regression-line/type.ts index 813e322161..5badb72df6 100644 --- a/packages/vchart-extension/src/components/regression-line/type.ts +++ b/packages/vchart-extension/src/components/regression-line/type.ts @@ -5,8 +5,21 @@ import type { ITextGraphicAttribute } from '@visactor/vrender-core'; +/** + * 回归线数据格式 + */ export interface RegressionLineData { + /** + * 颜色值 + */ + color?: string; + /** + * 回归线数据点 + */ line: { x: number; y: number }[]; + /** + * 置信区间数据点 + */ area?: { x: number; y: number; y1: number }[]; } @@ -15,10 +28,6 @@ export interface RegressionLineAttrs extends IGroupGraphicAttribute { * 用于区分的名称 */ name?: string; - /** - * 颜色值 - */ - color?: string; /** * 回归线配置 */ diff --git a/packages/vchart-extension/src/components/scatter-regression-line/index.ts b/packages/vchart-extension/src/components/scatter-regression-line/index.ts index 016f09b26d..1e50de1d2a 100644 --- a/packages/vchart-extension/src/components/scatter-regression-line/index.ts +++ b/packages/vchart-extension/src/components/scatter-regression-line/index.ts @@ -64,7 +64,8 @@ export function getScatterRegressionLineConfig( if (series && series.length) { series.forEach(s => { const region = s.getRegion().getLayoutStartPoint(); - + const colorAttrOptions = s.getColorAttribute(); + const groups = s.getSeriesKeys(); const data = s.getViewData().latestData; const fieldX = s.fieldX?.[0]; const fieldY = s.fieldY?.[0]; @@ -72,33 +73,42 @@ export function getScatterRegressionLineConfig( if (!fieldX || !fieldY || !data || data.length <= 2) { return; } - const { evaluateGrid, confidenceInterval } = getRegressionByType( - type, - data, - (datum: Datum) => datum?.[fieldX], - (datum: Datum) => datum?.[fieldY], - config.polynomialDegree - ); - const N = Math.min(3, Math.floor(data.length / 4)); - const lineData = evaluateGrid(N); - const confidenceData = confidenceInterval(N); - regressionData.push({ - line: lineData.map((ld: Datum) => { - const d = { [fieldX]: ld.x, [fieldY]: ld.y }; - return { - x: s.dataToPositionX(d) + region.x, - y: s.dataToPositionY(d) + region.y - }; - }), - area: confidenceData.map((c: Datum) => { - const d = { [fieldX]: c.x, [fieldY]: c.lower }; - return { - x: s.dataToPositionX(d) + region.x, - y: s.dataToPositionY(d) + region.y, - y1: s.dataToPositionY({ [fieldY]: c.upper }) + region.y - }; - }) + groups.forEach(group => { + const groupData = data.filter((d: Datum) => d[colorAttrOptions?.field] === group); + + if (!groupData.length) { + return; + } + const { evaluateGrid, confidenceInterval } = getRegressionByType( + type, + groupData, + (datum: Datum) => datum?.[fieldX], + (datum: Datum) => datum?.[fieldY], + config.polynomialDegree + ); + const N = Math.max(3, Math.floor(groupData.length / 4)); + const lineData = evaluateGrid(N); + const confidenceData = confidenceInterval(N); + + regressionData.push({ + color: color ?? colorAttrOptions?.scale?.scale(group), + line: lineData.map((ld: Datum) => { + const d = { [fieldX]: ld.x, [fieldY]: ld.y }; + return { + x: s.dataToPositionX(d) + region.x, + y: s.dataToPositionY(d) + region.y + }; + }), + area: confidenceData.map((c: Datum) => { + const d = { [fieldX]: c.x, [fieldY]: c.lower }; + return { + x: s.dataToPositionX(d) + region.x, + y: s.dataToPositionY(d) + region.y, + y1: s.dataToPositionY({ [fieldY]: c.upper }) + region.y + }; + }) + }); }); }); } @@ -107,8 +117,7 @@ export function getScatterRegressionLineConfig( }, line, confidenceInterval, - label, - color + label } }; } diff --git a/packages/vchart-extension/src/components/scatter-regression-line/type.ts b/packages/vchart-extension/src/components/scatter-regression-line/type.ts index 4bbeaeaf54..73fbee342e 100644 --- a/packages/vchart-extension/src/components/scatter-regression-line/type.ts +++ b/packages/vchart-extension/src/components/scatter-regression-line/type.ts @@ -6,11 +6,22 @@ export interface ScatterRegressionLineAttrs extends RegressionLineAttrs { * 多项式回归的阶数,仅当 type 为 polynomial 时有效 */ polynomialDegree?: number; + /** + * logisitc 回归时,打标字段对应的数据字段名称 + */ + logisiticLabelField?: string; } export interface ScatterRegressionLineSpec extends Partial< - Pick + Pick > { + /** + * 是否显示回归线 + */ visible?: boolean; + /** + * 主色,可以不设置,默认取散点图系列颜色 + */ + color?: string; }