diff --git a/unit-histogram/.eslintrc.json b/unit-histogram/.eslintrc.json new file mode 100644 index 0000000..d89eeca --- /dev/null +++ b/unit-histogram/.eslintrc.json @@ -0,0 +1,27 @@ +{ + "extends": "airbnb-base", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "no-param-reassign": [0], + "no-use-before-define": ["error", { "functions": false }], + "max-len": [0], + "import/prefer-default-export": [0], + "import/extensions": [0], + "import/no-unresolved": [0], + "import/no-extraneous-dependencies": [0], + "indent": ["error", 4] + }, + "env": { + "browser": true + }, + "plugins": [ + "html" + ], + "settings": { + "html/html-extensions": [ + ".html" + ] + } +} diff --git a/unit-histogram/data.csv b/unit-histogram/data.csv new file mode 100644 index 0000000..d542ed8 --- /dev/null +++ b/unit-histogram/data.csv @@ -0,0 +1,537 @@ +name,value,highlight +YELLOW DOT LIMITED,-80.6,no +Three Rivers District Council,-42,no +Lathams Ltd.,-34,no +The Crown Estate Commissioners,-31,no +Be Modern Ltd.,-27.7,no +Eastgate Care Group Ltd,-27.5,no +FORMICA LIMITED,-23.1,no +ROYAL BRITISH LEGION INDUSTRIES LTD.,-23,no +Houghton PLC,-22.5,no +PROJECT MANAGEMENT (STAFFORDSHIRE) LIMITED,-19.1,no +LOCAL CARE DIRECT LIMITED,-18.5,no +Your Homes Newcastle Ltd.,-16.5,no +Aston Manor Ltd.,-16,no +Tracsis PLC,-15.8,no +KLOECKNER METALS UK LTD,-15.4,no +Arnold Clark Finance Ltd..,-15,no +The Donaldson Trust,-15,no +Campbell's Prime Meat Ltd.,-13.1,no +The Quality Furniture Co. Ltd.,-12.9,no +Hambleton District Council,-12.3,no +OLDHAM COMMUNITY LEISURE LIMITED,-11.2,no +R & R.C.BOND (WHOLESALE) LIMITED,-10.9,no +I4 Pay Partners Ltd.,-10,no +Diageo Great Britain Ltd.,-9.8,no +Katharine House Hospice,-9.3,no +Castell Howell Foods Ltd.,-8.2,no +The Commission for Equality and Human Rights,-8.2,no +Milkwood Care Ltd,-7.9,no +Robert Gordon's College,-7.9,no +THE JPM GROUP COMPANIES LTD,-7.9,no +A3D2 Ltd.,-7,no +Biffa Environmental Municipal Services Ltd.,-5.7,no +Lawrence David Ltd.,-5.7,no +BPDTS,-5.5,no +Naylor Industries PLC,-5,no +BARFOOTS OF BOTLEY LIMITED,-4.8,no +Sweet Dreams (Nelson) Ltd.,-4.7,no +F.W. Evans Cycles (UK) Ltd.,-4.1,no +Cardinal Security Ltd.,-4,no +The British Museum,-4,no +SSE ENERGY SUPPLY LIMITED,-3.8,no +PRINCESS ALICE HOSPICE,-3.6,no +SMITH & REED RECRUITMENT (SW) LIMITED,-3.6,no +Borough of Poole,-3.2,no +OMAR PARK HOMES LIMITED,-3,no +THE OUTWARD BOUND TRUST,-3,no +TWINKL LTD,-3,no +CHROMALLOY UNITED KINGDOM LIMITED,-2.8,no +Vivacity Culture And Leisure,-2.8,no +Creamline Dairies Ltd.,-2.6,no +New Charter Housing Trust Ltd.,-2.6,no +Saint Elizabeth's School,-2.3,no +T.R. Fastenings Ltd.,-2.2,no +ARRK EUROPE LIMITED,-2.1,no +North East Autism Society,-2.1,no +Bighams Ltd.,-2,no +DIESEL (LONDON) LIMITED,-2,no +Independence Matters C.I.C.,-2,no +Northern Schools Trust,-1.9,no +Cashino Gaming Ltd.,-1.8,no +Rossall School,-1.7,no +UK MAIL LIMITED,-1.5,no +"WESCO AIRCRAFT EMEA, LTD.",-1.5,no +Gsl Dardan Ltd.,-1.4,no +AMTICO INTERNATIONAL LIMITED,-1.3,no +UNILEVER UK LIMITED,-1.3,no +Care Quality Commission,-1,no +Heritage Manor Ltd.,-1,no +EDINBURGH LEISURE,-0.9,no +KONDOR LIMITED,-0.7,no +LOUVER-LITE LIMITED,-0.7,no +Pramacare,-0.7,no +NATIONAL GRID GAS PLC,-0.6,no +Mobile Windscreens Ltd.,-0.5,no +Norwood Schools Ltd.,-0.5,no +ST CUTHBERT'S CARE,-0.5,no +THE ROYAL HORTICULTURAL SOCIETY,-0.4,no +South Essex Special Needs Housing Association Ltd.,-0.3,no +"Glatfelter Lydney, Ltd.",-0.1,no +Saint John Of God Hospitaller Services,-0.1,no +A Khan Restaurants Ltd.,0,no +Abbotsford Care (Glenrothes) Ltd.,0,no +"Advisory, Conciliation and Arbitration Service",0,no +Age UK North Tyneside,0,no +Arthur David (Food With Service) Ltd.,0,no +"Arts Club(London),Ltd.(The)",0,no +Autism Together,0,no +Bags Etc Ltd.,0,no +Boreal Ltd.,0,no +Broxtowe Borough Council,0,no +Bulloughs Cleaning Services Ltd.,0,no +Cherry Lane Retail Centres Ltd.,0,no +Chorley Borough Council,0,no +Cleveland Police,0,no +College of Haringey Enfield & North East London,0,no +Community Lives Consortium,0,no +Connect Academy Trust,0,no +Cornerstone Community Care,0,no +DALE CARE LIMITED,0,no +Department Of Work And Pensions,0,no +Devon & Cornwall Autistic Community Trust,0,no +Dingbro Ltd.,0,no +Emh Care And Support Ltd.,0,no +Emporia Leisure Ltd.,0,no +Erskine Hospital,0,no +EXPD8 LIMITED,0,no +FDM GROUP LIMITED,0,no +Florin Industrial Services Holdings Ltd.,0,no +Fore Street Employment Agency Ltd.,0,no +Gainford Hotels Ltd.,0,no +Gainpeak Ltd.,0,no +HALL CLEANING SERVICES LIMITED,0,no +Harrogate Council,0,no +Independent Catering Management Ltd.,0,no +Industrial Site Maintenance Ltd,0,no +Kindertons Ltd.,0,no +Kingston Smith Group Services Ltd.,0,no +Kms (UK) Ltd,0,no +Liberty Leisure Limited,0,no +Livewire (Warrington) Cic,0,no +Lloyd Shoe Co Ltd.,0,no +LONGACRES GARDEN CENTRE LIMITED,0,no +Lorimer Care Homes Ltd.,0,no +M & D (Leisure) Ltd.,0,no +Minster Care Management Ltd.,0,no +N. Notaro Homes Ltd.,0,no +One Call Recruitment Ltd.,0,no +Oxford Archaeology Ltd.,0,no +Pacific Care Ltd.,0,no +Peartree Cleaning Services Holdings Ltd.,0,no +Penumbra,0,no +Porthaven Group Holdings Ltd.,0,no +Registers of Scotland,0,no +RENAISSANCE CARE (NO1) LIMITED,0,no +RETHINK MENTAL ILLNESS LTD,0,no +RIBBON ACQUISITION LIMITED,0,no +SADLER'S WELLS TRUST LIMITED,0,no +Sefton New Directions Ltd.,0,no +SENSE SCOTLAND,0,no +SOUTHDOWN HOUSING ASSOCIATION LIMITED,0,no +Southside Partnership,0,no +SSE METERING LIMITED,0,no +Style Acre,0,no +Summit Recruitment Ltd.,0,no +The Bartrum Group Ltd.,0,no +THE CELTIC MANOR RESORT LIMITED,0,no +Van Hage & Co. (Holdings) Ltd.,0,no +Walter Davidson & Sons Ltd.,0,no +Watt Brothers (Glasgow And Edinburgh) Ltd.,0,no +Wright's Pies (Shelton) Ltd.,0,no +YHA (ENGLAND AND WALES),0,no +Sage (UK) Ltd,0.1,no +ST MUNGO COMMUNITY HOUSING ASSOCIATION,0.1,no +The Royal Masonic Benevolent Institution Care Co.,0.1,no +North Ayrshire Leisure Ltd.,0.2,no +The Information Commissioner's Office,0.2,no +UK Armed Forces,0.2,no +Integrated Cleaning Management Ltd.,0.3,no +Neovia Logistics Services (U.K.) Ltd.,0.3,no +Mirus-Wales,0.4,no +Niftylift Ltd.,0.4,no +United Response,0.4,no +The Press Association Ltd.,0.5,no +Union Of Uea Students Ltd.,0.6,no +Arjo Wiggins Fine Papers Ltd.,0.7,no +HR ESSENTIALS LIMITED,0.7,no +MJ Gleeson PLC,0.7,no +Sogeti UK Ltd.,0.7,no +Biffa Municipal Ltd.,0.8,no +GLENSIDE MANOR HEALTHCARE SERVICES LIMITED,0.9,no +Wolseley UK Ltd.,0.9,no +Europa Worldwide Logistics Ltd,1,no +J5C Management Ltd.,1,no +Manor Restaurants (UK) Ltd.,1,no +Rhubarb Food Design Ltd.,1,no +TATA CHEMICALS EUROPE LIMITED,1,no +"The Bristol, Gloucestershire, Somerset And Wiltshire Community Rehabilitation Co. Ltd.",1,no +Vision Security Group Ltd.,1,no +Dnata Ltd.,1.1,no +EAST OF ENGLAND CO-OPERATIVE SOCIETY LIMITED,1.1,no +Bon Accord Care Ltd.,1.2,no +PORK FARMS LIMITED,1.2,no +EAST MIDLANDS CONFERENCE CENTRE LIMITED,1.4,no +Forestry Commission,1.4,no +Oliver Bonas Ltd.,1.4,no +Wesc Foundation,1.4,no +Niab.,1.5,no +Mama Bear's Day Nursery Ltd,1.6,no +Wyre Council,1.6,no +Natural Resources Wales,1.7,no +Gedling Borough Council,1.9,no +NATIONAL GRID UK LIMITED,1.9,no +Ladbrokes Betting & Gaming Ltd.,2,no +"THE KENT, SURREY AND SUSSEX COMMUNITY REHABILITATION COMPANY LIMITED",2,no +ALCOHOL & DRUGS ACTION,2.1,no +KNIGHTON FOODS LIMITED,2.1,no +Merseyside Fire and Rescue Service,2.3,no +Lilian Faithfull Homes,2.4,no +Ladbrokes Coral Group PLC,2.5,no +Department for International Trade,2.7,no +FLORETTE UK + IRELAND LIMITED,2.7,no +Hyndburn Borough Council,2.7,no +Cleveland Fire Brigade,3,no +Moto Hospitality Ltd.,3,no +Planet Organic Ltd.,3,no +Quadrant Catering Ltd.,3,no +Marlow Foods Ltd.,3.1,no +DERWEN COLLEGE,3.2,no +Hard Rock Cafe (UK) Ltd.,3.2,no +HARD ROCK INTERNATIONAL LIMITED,3.2,no +Tillery Valley Foods Ltd.,3.2,no +Acenta Steel Ltd.,3.4,no +Chichester District Council,3.4,no +BIFFA WASTE SERVICES LIMITED,3.6,no +Royal Berkshire Fire & Rescue Service,3.7,no +SHELL SHARED SERVICE CENTRE - GLASGOW LIMITED,3.7,no +DANIEL THWAITES PUBLIC LIMITED COMPANY,3.8,no +Myfresh Prepared Produce Ltd.,3.8,no +Wigan Leisure And Culture Trust,3.8,no +"The Bedfordshire, Northamptonshire, Cambridgeshire And Hertfordshire Community Rehabilitation Co. Lt",3.9,no +The Cumbria And Lancashire Community Rehabilitation Co. Ltd.,3.9,no +Coral Racing Ltd.,4,no +Crystal Services PLC,4,no +Outlook Care,4,no +The Manor House Hotel (Castle Combe) Ltd.,4,no +THE SOUTHERN CO-OPERATIVE LIMITED,4,no +Wasdell Packaging Ltd.,4,no +Kingspan,4.1,no +HIGH LIFE HIGHLAND,4.3,no +NUMATIC INTERNATIONAL LIMITED,4.3,no +BELLS OF LAZONBY LIMITED,4.4,no +Signature Senior Lifestyle Operations Ltd,4.4,no +Voluntary Service Overseas,4.5,no +EDEN PROJECT LIMITED,4.7,no +Hugo Boss UK Ltd.,4.7,no +Michael I Holdsworth Ltd.,4.7,no +Camphill Village Trust Ltd.(The),4.8,no +Maidstone Borough Council,4.9,no +Regular Cleaning Services Ltd.,4.9,no +St.Helen's School Northwood,4.9,no +Syntel Europe Ltd.,4.9,no +THE DAUGHTERS OF CHARITY OF ST. VINCENT DE PAUL SERVICES,4.9,no +WEETABIX LIMITED,4.9,no +ACHILLES INFORMATION LIMITED,5,no +Axminster Tool Centre Ltd,5,no +BLACK SWAN INTERNATIONAL LIMITED,5,no +CONTRACTOR UMBRELLA LIMITED,5,no +Styles & Brown Ltd,5,no +The Sandwell Community Caring Trust,5,no +Swallowfield PLC,5.2,no +Genus UK Ltd.,5.3,no +ST. ANN'S HOSPICE,5.4,no +Leeds Arts University,5.7,no +PORK FARMS CASPIAN LIMITED,5.8,no +Department for Education,5.9,no +Paultons Park Ltd.,5.9,no +Charlies Stores Ltd.,6,no +Dunster House Ltd.,6,no +Ideal Carehomes (Number One) Ltd.,6,no +Solent Pizza Delivery Ltd.,6,no +Solent Pizza W Ltd.,6,no +ST ANDREWS BREWERS LIMITED,6,no +SUSTRANS LIMITED,6,no +Greater London Authority,6.1,no +Rolls-Royce PLC,6.3,no +National Institute For Health And Care Excellence,6.4,no +S & B Commercials PLC,6.4,no +Epayroll Services Ltd.,6.6,no +Newcastle City Council,6.7,no +Department for International Development,6.8,no +WATERFIELDS (LEIGH) LIMITED,6.8,no +Dorchester Hotel Ltd.,7,no +FORTEM SOLUTIONS LIMITED,7,no +The Action Group,7,no +NATIONAL EXHIBITION CENTRE LIMITED (THE),7.1,no +Support For Living Ltd.,7.1,no +M.P. Moran & Sons Ltd.,7.2,no +CENTRAL ENGLAND CO-OPERATIVE LIMITED,7.5,no +Catholic Agency For Overseas Development,7.6,no +Don & Low Ltd.,7.8,no +3M UNITED KINGDOM PUBLIC LIMITED COMPANY,8,no +Kingspan Insulation Ltd.,8,no +Smh Fleet Solutions Ltd.,8,no +West Yorkshire Fire and Rescue Service,8,no +NHS Resolution formerly NHS Litigation Authority,8.1,no +Department for Culture Media & Sport,8.2,no +DONCASTER CHILDREN'S SERVICES TRUST LIMITED,8.2,no +Rolls-Royce Marine Power Operations Ltd.,8.2,no +Rwe Generation UK PLC,8.4,no +Risedale Estates Ltd.,8.5,no +Novartis Pharmaceuticals UK Ltd.,8.6,no +Vacherin Ltd.,8.7,no +Avante Care And Support Ltd.,8.8,no +Department For Exiting The European Union,8.9,no +Working Links (Employment) Ltd.,8.9,no +ADNAMS PLC,9,no +The Village Academy,9,no +British Broadcasting Corporation,9.3,no +REVENUE & CUSTOMS DIGITAL TECHNOLOGY SERVICES LIMITED,9.3,no +Bodycote Heat Treatments Ltd.,9.6,no +Department for Communities and Local Government,9.8,no +HML HOLDINGS PLC,9.8,no +University Of Kent,9.8,no +Dana UK Axle Ltd.,10,no +Diocese Of Southwell And Nottingham Multi-Academy Trust,10,no +NPOWER YORKSHIRE LIMITED,10,no +Havelock Europa PLC,10.1,no +SOCIAL INTEREST GROUP,10.1,no +Accenture (UK) Ltd.,10.2,no +Oil States Industries (UK) Ltd.,10.4,no +Chemring Countermeasures Ltd.,10.5,no +Ministry of Justice,10.6,no +Arnold Clark Automobiles Ltd.,10.8,no +SEETEC BUSINESS TECHNOLOGY CENTRE LIMITED,10.8,no +THE CHARTERED INSTITUTE OF PERSONNEL AND DEVELOPMENT,10.8,no +Wycombe District Council,10.8,no +Kuehne + Nagel Ltd.,11,no +Network Rail Infrastructure Ltd.,11,no +BALANS RESTAURANTS LIMITED,11.1,no +Foreign & Commonwealth Office,11.1,no +INN ON THE PARK (LONDON) LIMITED,11.1,no +INTERFLOOR LIMITED,11.1,no +Corby Borough Council,11.2,no +Hayley Group Ltd.,11.2,no +Sodexo Ltd,11.2,no +BROMFORD HOUSING GROUP LIMITED,11.4,no +Beacon Bingo Ltd.,11.5,no +Surface Technology International Ltd.,11.7,no +Alliance In Partnership Ltd.,11.9,no +Chartwells Hounslow (Feeding Futures) Ltd.,12,no +South Gloucestershire Council,12,no +Trelleborg Offshore UK Ltd.,12,no +DELOITTE LLP,12.1,no +"Department, for Environment, Food and Rural Affairs",12.1,no +LAGARDÈRE TRAVEL RETAIL (UK) LTD,12.2,no +PREMIER FOODS GROUP LIMITED,12.2,no +Shell U.K. Oil Products Ltd.,12.2,no +H M Government Cabinet Office,12.3,no +Rolls-Royce Power Engineering PLC,12.3,no +HM Revenue and Customs (HMRC),12.5,no +ASPIRE HOUSING LIMITED,12.9,no +Gates (U.K.) Ltd.,12.9,no +Rft Repairs Ltd.,12.9,no +Kingspan Ltd.,13,no +NPOWER LIMITED,13,no +SHOOSMITHS LLP,13,no +Cambridgeshire Police,13.1,no +Portsmouth Water Ltd.,13.1,no +PRICEWATERHOUSECOOPERS SERVICES LIMITED,13.1,no +Department Of Health,13.3,no +MAGDALEN COLLEGE SCHOOL OXFORD LIMITED,13.3,no +Harry Fairbairn Ltd.,13.4,no +FIRST WESSEX,13.5,no +British Medical Association,13.6,no +GREENVALE AP LIMITED,13.6,no +HM Treasury,13.7,no +"COMPASS GROUP, UK AND IRELAND LIMITED",14,no +NHS Digital,14.1,no +Truro and Penwith College,14.1,no +"MCKINSEY & COMPANY, INC. UNITED KINGDOM",14.3,no +Novartis Grimsby Ltd.,14.3,no +EMH HOUSING & REGENERATION LIMITED,14.4,no +National Grid Electricity Transmission PLC,14.5,no +Canford School,14.6,no +Ministry Of Defence,14.6,no +SEVERN TRENT WATER LIMITED,14.6,no +DL Insurance Services Ltd.,14.7,no +ORWELL HOUSING ASSOCIATION LIMITED,14.7,no +Tandridge District Council,14.7,no +ERNST & YOUNG SERVICES LIMITED,14.8,no +Sussex Coast College,14.8,no +UNILEVER U.K. CENTRAL RESOURCES LIMITED,14.9,no +Barking & Dagenham College,15,no +"Department for Business, Energy & Industrial Strategy",15,no +Portsmouth City Council,15,no +Home Office,15.1,no +The Pirbright Institute,15.1,no +The National Gallery,15.2,no +UNITED UTILITIES WATER LIMITED,15.2,no +Lockheed Martin UK Ampthill Ltd.,15.3,no +THAMES WATER UTILITIES LIMITED,15.4,no +RADIAN CAPITAL PLC,15.7,no +United Utilities Group PLC,15.9,no +ONE YMCA ,16,no +Royal Garden Hotel Ltd.,16,no +Millbrook Group Ltd.,16.1,no +Disability Challengers,16.3,no +UK Export Finance,16.3,no +SHELL INTERNATIONAL PETROLEUM COMPANY LIMITED,16.5,no +Surrey Satellite Technology Ltd.,16.5,no +Awe Management Ltd.,16.7,no +Awe PLC,16.7,no +DIAGEO SCOTLAND LIMITED,16.7,no +Ove Arup & Partners International Ltd.,16.7,no +RSM UK Tax and Accounting Limited,16.7,no +United Utilities PLC,16.7,no +Anglian Water Services Ltd.,16.9,no +Gloucestershire Hospitals Nhs Foundation Trust,16.9,no +CAPGEMINI UK PLC,17,no +Wolverhampton Homes,17,no +KELTRUCK LIMITED,17.3,no +VIRGIN MEDIA LIMITED,17.4,no +DELOITTE MCS LIMITED,17.8,no +FUJITSU SERVICES LIMITED,17.9,no +Lawn Tennis Association Ltd.,18,no +FLAGSHIP HOUSING GROUP LIMITED,18.3,no +SOCIETY OF LICENSED VICTUALLERS,18.3,no +The Gorse Academies Trust,18.4,no +Her Majesty's Land Registry,18.5,no +National Heritage Memorial Fund,18.6,no +SACO THE SERVICED APARTMENT COMPANY LIMITED,18.7,no +Sodexo Remote Sites Scotland Ltd.,18.7,no +SOUTHERN ELECTRIC POWER DISTRIBUTION PLC,18.7,no +ROWE FARMING LIMITED,18.9,no +Glasswells Ltd.,19.1,no +Furnico Furniture Ltd.,19.3,no +SSE PLC,19.3,no +MOOR END ACADEMIES TRUST ,19.5,no +OXFORD INSTRUMENTS NANOTECHNOLOGY TOOLS LIMITED,19.9,no +St Bartholomew's School,19.9,no +HUDSON GLOBAL RESOURCES LIMITED,20,no +INNOGY RENEWABLES UK LIMITED,20,no +Mott Macdonald Group Ltd.,20,no +Woodard Academies Trust,20,no +SCOTTISH HYDRO ELECTRIC POWER DISTRIBUTION PLC,20.1,no +Telefonica UK Ltd.,20.2,no +Aci Worldwide (Emea) Ltd.,20.3,no +Leonardo Mw Ltd,20.4,no +Sage Group (The) PLC,20.5,no +MC TRUCK & BUS LIMITED,20.7,no +TRAC GROUP LIMITED,20.7,no +Tes Global Ltd.,20.8,no +THE CHURCH OF ENGLAND CHILDREN'S SOCIETY,20.8,no +SSE CONTRACTING LIMITED,20.9,no +The Financial Conduct Authority,20.9,no +ALLIANCE MEDICAL LIMITED,21,no +Imperial Commercials Ltd,21,no +TRG LOGISTICS LTD,21,no +Doncaster Metropolitan Borough Council,21.1,no +Ford & Slater Ltd.,21.1,no +Strevens Vehicles Holdings Ltd.,21.1,no +WALES HIGH SCHOOL ACADEMY TRUST ,21.1,no +BDO SERVICES LIMITED,21.2,no +Baker Tilly Management Ltd.,21.5,no +S.G. Petch Ltd.,21.9,no +Atb Group UK Ltd.,22,no +The Two Counties Trust,22.1,no +Department For Transport,22.6,no +The Co-Operative Bank PLC,22.6,no +SHELL U.K. LIMITED,22.7,no +Third Bridge Group Ltd.,22.8,no +Warwickshire College,22.9,no +CITRIX R&D LIMITED,23.2,no +Ssl Group (UK) Ltd.,23.2,no +Bracknell Forest Council,23.3,no +Liverpool Victoria Friendly Society Limited,23.5,no +Oxford Diocesan Schools Trust,23.7,no +SHELL INTERNATIONAL TRADING AND SHIPPING COMPANY LIMITED,24,no +TSB BANK PLC,24,no +Bank of England,24.2,no +national employment savings trust,24.2,no +Lockheed Martin UK Ltd.,24.3,no +SSE HOME SERVICES LIMITED,24.6,no +T Brown Group Ltd.,24.7,no +Ecclesiastical Insurance Office PLC,25,no +Crown Prosecution Services,25.3,no +Broadland District Council,25.5,no +New College Durham,25.6,no +SHELL INTERNATIONAL LIMITED,25.7,no +Gsm Automotive Holdings Ltd.,25.8,no +Royal Orthopaedic Hospital,25.9,no +Advanced Travel Partners UK Ltd,26,no +Health & Safety Executive,26,no +Shell Research Ltd.,26.5,no +The Wilkins Group Ltd.,26.8,no +BWB CONSULTING LIMITED,26.9,no +SSE GENERATION LIMITED,27,no +Wcf Ltd.,27.3,no +Grosvenor Estate Management Ltd.,27.6,no +ST BENEDICT'S SCHOOL EALING,27.7,no +CAPITAL (HAIR AND BEAUTY) LIMITED,27.9,no +Chemring Energetics UK Ltd.,28,no +Formaplex Ltd.,28,no +Medivet Group Ltd.,28,no +CHARCOALBLUE LLP,28.5,no +Frederic Robinson Ltd.,28.6,no +Yorkshire Building Society,28.6,no +Cooper Topco Ltd.,29,no +INNOGY BUSINESS SERVICES UK LIMITED,29,no +Whp Telecoms Ltd.,29,no +SSE SERVICES PLC,29.5,no +The Medical Protection Society Ltd.,29.5,no +Cundall Ltd.,29.6,no +Darlington College Of Technology,30,no +The Shared Learning Trust,30,no +Oakham School,30.3,no +Excalibur Academies Trust,31.9,no +Tenet Group Ltd.,32,no +Rider Levett Bucknall UK Ltd.,32.7,no +Cms Cameron Mckenna Nabarro Olswang Services Ltd.,32.8,no +LENDLEASE CONSTRUCTION (EUROPE) LIMITED,33,no +Tonbridge & Malling Borough Council,33.6,no +Ridge And Partners LLP,34,no +Aim Aviation (Jecco) Ltd.,34.3,no +PRICEWATERHOUSECOOPERS LLP,34.4,no +RWE SUPPLY & TRADING GMBH,35.4,no +ALDERMORE GROUP PLC,35.7,no +The Rowan Learning Trust,35.9,no +Clydesdale Bank PLC,36,no +SCOTTISH HYDRO ELECTRIC TRANSMISSION PLC,36.1,no +Land Securities Properties Ltd.,36.3,no +SMART Multi Academy Trust,36.3,no +VIRGIN MONEY PLC,38.4,no +EXCHANGE HOUSE SERVICES LIMITED,38.8,no +RIver Learning Trust,39,no +Carter Synergy Ltd.,39.4,no +Indigo Sun Retail Ltd.,39.7,no +Linbrooke Services Ltd.,39.8,no +BILFINGER INDUSTRIAL SERVICES UK LIMITED,39.9,no +Step Academy Trust,40,no +OCTOPUS CAPITAL LIMITED,40.3,no +National Church Institutions,41,no +Eastern Multi-Academy Trust,42.5,no +Truro & Penwith Academy Trust,43.5,no +Trinity Multi Academy Trust,44.7,no +Easyjet Airline Co. Ltd.,45.5,no +Bsw Heating Ltd,46.5,no +The First Federation Trust,47.6,no +Lady Manners School,52.6,no +Invictus Education Trust,54.2,no +PHASE EIGHT (FASHION & DESIGNS) LIMITED,54.5,no +OCEAN LEARNING TRUST ,55,no +The Office for Nuclear Regulation,55.3,no +Healing Multi Academy Trust,55.5,no +Peninsula Learning Trust,59.8,no +Rectella Ltd.,88,no diff --git a/unit-histogram/drawChart.js b/unit-histogram/drawChart.js new file mode 100644 index 0000000..59ce2d1 --- /dev/null +++ b/unit-histogram/drawChart.js @@ -0,0 +1,369 @@ +import * as d3 from 'd3'; +import gChartcolour from 'g-chartcolour'; + + +export function draw() { + // let dataset = []; + let rem = 10; + let yScale0 = d3.scaleLinear(); + let yScale1 = d3.scaleBand(); + let xScale0 = d3.scaleLinear(); + let xScale1 = d3.scaleBand(); + let colourThresholds = []; + let seriesNames = []; + let highlightNames = []; + let selectedNames = []; + let yAxisAlign = 'right'; + let markers = false; + const includeAnnotations = d => (d.annotate !== '' && d.annotate !== undefined); // eslint-disable-line + let annotate = false; // eslint-disable-line + let interpolation = d3.curveLinear; + const colourScale = d3.scaleThreshold(); + // .range(gChartcolour.lineWeb) + // .domain(seriesNames); + + function chart(parent) { + + const unitG = parent.append('g'); + + colourScale + .domain(colourThresholds); + + + unitG.selectAll('unit') + .data( d => d.values) + .enter() + .append('rect') + .classed('unit', true) + .classed('annotations', d => d.highlight == 'yes' ? 'yes' : 'no') + .attr('x', d => xScale0( d.bin )) + .attr('y', d => yScale0( d.y ) - yScale1.bandwidth()) + .attr('width', d => xScale1.bandwidth()) + .attr('height', d => yScale1.bandwidth()) + .style('fill', d => colourScale(d.bin)) + .style('stroke', d => d.highlight == 'yes' ? 'black' : 'none') + .style('stroke-width', .6) + // .style('opacity', d => d.highlight == 'yes' ? 1 : .7); + + + + } + + + chart.yScale0 = (d) => { + if (!d) return yScale0; + yScale0 = d; + return chart; + }; + + chart.yDomain0 = (d) => { + if (typeof d === 'undefined') return yScale0.domain(); + yScale0.domain(d); + return chart; + }; + + chart.yRange0 = (d) => { + if (typeof d === 'undefined') return yScale0.range(); + yScale0.range(d); + return chart; + }; + + chart.yScale1 = (d) => { + if (!d) return yScale1; + yScale1 = d; + return chart; + }; + + chart.yDomain1 = (d) => { + if (typeof d === 'undefined') return yScale1.domain(); + yScale1.domain(d); + return chart; + }; + + chart.yRange1 = (d) => { + if (typeof d === 'undefined') return yScale1.range(); + yScale1.range(d); + return chart; + }; + + chart.yAxisAlign = (d) => { + if (!d) return yAxisAlign; + yAxisAlign = d; + return chart; + }; + + chart.seriesNames = (d) => { + if (typeof d === 'undefined') return seriesNames; + seriesNames = d; + return chart; + }; + + chart.xScale0 = (d) => { + if (!d) return xScale0; + xScale0 = d; + return chart; + }; + + chart.xDomain0 = (d) => { + xScale0.domain(d); + return chart; + }; + + chart.xRange0 = (d) => { + xScale0.rangeRound(d); + return chart; + }; + + chart.xScale1 = (d) => { + if (!d) return xScale1; + xScale1 = d; + return chart; + }; + + chart.xDomain1 = (d) => { + xScale1.domain(d); + return chart; + }; + + chart.xRange1 = (d) => { + xScale1.rangeRound(d); + return chart; + }; + + chart.plotDim = (d) => { + if (!d) return window.plotDim; + window.plotDim = d; + return chart; + }; + + chart.rem = (d) => { + if (!d) return rem; + rem = d; + return chart; + }; + + + chart.annotate = (d) => { + annotate = d; + return chart; + }; + + chart.dataset = (d) => { + dataset = d; + return chart; + }; + + chart.markers = (d) => { + if (typeof d === 'undefined') return markers; + markers = d; + return chart; + }; + + chart.interpolation = (d) => { + if (!d) return interpolation; + interpolation = d; + return chart; + }; + + chart.colourThresholds = (d) => { + colourThresholds = d; + return chart; + }; + + chart.selectedNames = (d) => { + selectedNames = d; + return chart; + }; + + + + chart.colourPalette = (d) => { + if (!d) return colourScale; + if (highlightNames.length > 0) { + if (d === 'social' || d === 'video') { + colourScale.range(gChartcolour.mutedFirstLineSocial); + } else if (d === 'webS' || d === 'webM' || d === 'webMDefault' || d === 'webL') { + colourScale.range(gChartcolour.mutedFirstLineWeb); + } else if (d === 'print') { + colourScale.range(gChartcolour.mutedFirstLinePrint); + } + return chart; + } + if (d === 'social' || d === 'video') { + colourScale.range(gChartcolour.lineSocial); + } else if (d === 'webS' || d === 'webM' || d === 'webMDefault' || d === 'webL') { + colourScale.range(gChartcolour.lineWeb); + } else if (d === 'print') { + colourScale.range(gChartcolour.linePrint); + } + return chart; + }; + + return chart; +} + + function addLabels(plotData, parent, rem){ + + const labelG = parent.append('g'); + + const labelData = plotData.filter( d => d.highlight == 'yes'); + + console.log(plotData[0]) + + + const labels = labelG.selectAll('g') + .data(labelData) + .enter() + .append('g'); + + + + + + + labels.call( p => { + + // console.log(plotData) + + p.append('line') + .attr('x1', d => xScale0(d.bin) + (xScale1.bandwidth()/2)) + .attr('x2', d => xScale0(d.bin) + (xScale1.bandwidth()/2)) + .attr('y1', d => yScale0(d.y)) + .attr('y2', d => yScale0(d.y) + rem) + .style('stroke','#000000') + .style('stroke-width', rem/10) + // .style('stroke-dasharray',[4,2]); + + p.append('text') + .attr('x', d => xScale(d.bin) + (xScale1.bandwidth()/2)) + .attr('y', d => d3.max([yScale1(d.ypos) + rem ,0])) + .style('font-family','metric') + .style('font-size',16) + .style('fill','#000') + .html( d => d.name + ' ' + d.value + '%') + + }) + } + + export function drawAnnotations(){ + + let yScale0 = d3.scaleLinear(); + let yScale1 = d3.scaleBand(); + let xScale0 = d3.scaleLinear(); + let xScale1 = d3.scaleBand(); + let rem = 10; + + function annotations(parent) { + + const labelG = parent.append('g') + .attr('class','highlight'); + + const labels = labelG.selectAll('g') + .data(d => d.values) + .enter() + .append('g') + .attr('class','annotations-holder') + .call( p => { + + p.append('line') + .attr('x1', d => xScale0(d.bin) + (xScale1.bandwidth()/2)) + .attr('x2', d => xScale0(d.bin) + (xScale1.bandwidth()/2)) + .attr('y1', d => yScale0(d.y) - yScale1.bandwidth()) + .attr('y2', d => yScale0(d.y) - rem*2) + .style('stroke','#000000') + // .style('stroke-width', .6) + // .style('stroke-dasharray',[4,2]); + + p.append('text') + .attr('x', d => xScale0(d.bin) + (xScale1.bandwidth()/2)) + .attr('y', d => d3.max([yScale0(d.y) - rem*2,0])) + .attr('class','annotation') + // .style('font-family','metric') + // .style('font-size',16) + // .style('fill','#000') + .text( d => d.name + ' ' + d.value + '%') + + }) + + + } + + annotations.yScale0 = (d) => { + if (!d) return yScale0; + yScale0 = d; + return annotations; + }; + + annotations.yDomain0 = (d) => { + if (typeof d === 'undefined') return yScale0.domain(); + yScale0.domain(d); + return annotations; + }; + + annotations.yRange0 = (d) => { + if (typeof d === 'undefined') return yScale0.range(); + yScale0.range(d); + return annotations; + }; + + annotations.yScale1 = (d) => { + if (!d) return yScale1; + yScale1 = d; + return annotations; + }; + + annotations.yDomain1 = (d) => { + if (typeof d === 'undefined') return yScale1.domain(); + yScale1.domain(d); + return annotations; + }; + + annotations.yRange1 = (d) => { + if (typeof d === 'undefined') return yScale1.range(); + yScale1.range(d); + return annotations; + }; + + annotations.xScale0 = (d) => { + if (!d) return xScale0; + xScale0 = d; + return annotations; + }; + + annotations.xDomain0 = (d) => { + xScale0.domain(d); + return annotations; + }; + + annotations.xRange0 = (d) => { + xScale0.rangeRound(d); + return annotations; + }; + + annotations.xScale1 = (d) => { + if (!d) return xScale1; + xScale1 = d; + return annotations; + }; + + annotations.xDomain1 = (d) => { + xScale1.domain(d); + return annotations; + }; + + annotations.xRange1 = (d) => { + xScale1.rangeRound(d); + return annotations; + }; + + annotations.rem = (d) => { + if (!d) return rem; + rem = d; + return annotations; + }; + + + return annotations; +} + + diff --git a/unit-histogram/index.html b/unit-histogram/index.html new file mode 100644 index 0000000..378ed56 --- /dev/null +++ b/unit-histogram/index.html @@ -0,0 +1,63 @@ + + + + Wrapper-starter Visual Vocabulary + + + + + + + +

Chart title in here

+

The standard way to show a changing time series. If data are irregular, consider markers to represent data points

+

Some useful settings in the index.js +

+

+

Column headings in the csv +

+

+

Please make sure than the blue line is on top as this is the primary line colour

+ +
+ + + +

Non-responsive chart

+
+

Responsive image set

+
+
+
+
+
+
+ + + diff --git a/unit-histogram/index.js b/unit-histogram/index.js new file mode 100644 index 0000000..9c29a89 --- /dev/null +++ b/unit-histogram/index.js @@ -0,0 +1,261 @@ +/** + * Bootstrapping code for line chart + */ + +import * as d3 from 'd3'; +import * as gLegend from 'g-legend'; +import gChartframe from 'g-chartframe'; +import * as gAxis from 'g-axis'; +import * as parseData from './parseData.js'; +import * as unitHistogram from './drawChart.js'; + +const dataFile = 'data.csv'; + +const dateFormat = '%d/%m/%Y'; +/* + some common formatting parsers.... + '%m/%d/%Y' 01/28/1986 + '%d-%b-%y' 28-Jan-86 + '%Y %b' 1986 Jan + '%Y-%m-%d' 1986-01-28 + '%B %d' January 28 + '%d %b' 28 Jan + '%H:%M' 11:39 + '%H:%M %p' 11:39 AM + '%d/%m/%Y %H:%M' 28/01/2016 11:39 +*/ + +const sharedConfig = { + title: 'Title not yet added', + subtitle: 'Subtitle not yet added', + source: 'Source not yet added', +}; +//Put the user defined variablesin delete where not applicable +const yMin = 0;// sets the minimum value on the yAxis +const yMax = 100;// sets the maximum value on the xAxis +const xMin = -100; +const xMax = 100; +const yAxisHighlight = 0; // sets which tick to highlight on the yAxis +const numTicksy = 4;// Number of tick on the uAxis +const yAxisAlign = 'left';// alignment of the axis +const xAxisAlign = 'bottom';// alignment of the axis +const legendAlign = 'vert';// hori or vert, alignment of the legend +const legendType = 'line';// rect, line or circ, geometry of legend marker +const minorAxis = true;// turns on or off the minor axis +const binWidth = 1; //set the width of your bins. If possible, keep this to a unit the reader will understand +const colourThresholds = [0,1,100]; // choose where colors start and end. Comment out for one colour +const highlightText = 'British'; // a string. If this regex exists in d.name, the corresponding block will be highlighted + +// const colourThresholds = []; + + + +// Individual frame configuration, used to set margins (defaults shown below) etc +const frame = { + webS: gChartframe.webFrameS(sharedConfig) + .margin({ top: 100, left: 15, bottom: 82, right: 15 }) + // .title('Put headline here') // use this if you need to override the defaults + // .subtitle("Put headline |here") //use this if you need to override the defaults + .height(400), + + webM: gChartframe.webFrameM(sharedConfig) + .margin({ + top: 0, left: 10, bottom: 120, right: 15, + }) + // .title("Put headline here") + .height(500), + + webL: gChartframe.webFrameL(sharedConfig) + .margin({ + top: 100, left: 20, bottom: 104, right: 15, + }) + // .title("Put headline here") + .height(700) + .fullYear(true), + + webMDefault: gChartframe.webFrameMDefault(sharedConfig) + .margin({ + top: 100, left: 20, bottom: 86, right: 15, + }) + // .title("Put headline here") + .height(500), + + print: gChartframe.printFrame(sharedConfig) + .margin({ top: 40, left: 7, bottom: 35, right: 7 }) + // .title("Put headline here") + // .width(53.71)// 1 col + .width(112.25)// 2 col + // .width(170.8)// 3 col + // .width(229.34)// 4 col + // .width(287.88)// 5 col + // .width(346.43)// 6 col + // .width(74)// markets std print + .height(69.85), // std print (Use 58.21mm for markets charts that matter) + + social: gChartframe.socialFrame(sharedConfig) + .margin({ + top: 140, left: 50, bottom: 138, right: 40, + }) + // .title("Put headline here") + .width(612) + .height(612), // 700 is ideal height for Instagram + + video: gChartframe.videoFrame(sharedConfig) + .margin({ + left: 207, right: 207, bottom: 210, top: 233, + }), + // .title("Put headline here") +}; + + +// add the frames to the page... +d3.selectAll('.framed') + .each(function addFrames() { + const figure = d3.select(this) + .attr('class', 'button-holder'); + + figure.select('svg') + .call(frame[figure.node().dataset.frame]); + }); + +parseData.load(dataFile, { yMin, binWidth, highlightText }) + .then(({ bins, selectedNames, plotAnnos, plotData }) => { + Object.keys(frame).forEach((frameName) => { + const currentFrame = frame[frameName]; + + const myXAxis0 = gAxis.xLinear();// sets up xAxis + const myXAxis1 = gAxis.xOrdinal();// sets up xAxis + const myYAxis0 = gAxis.yLinear();// sets up xAxis + const myYAxis1 = gAxis.yOrdinal();// sets up xAxis + const myChart = unitHistogram.draw(); + const myAnnotations = unitHistogram.drawAnnotations(); + + // define other functions to be called + + const tickSize = currentFrame.dimension().width;// Used when drawing the yAxis ticks + + console.log(plotAnnos) + + + myYAxis0 + .range([currentFrame.dimension().height, 0]) + .domain([0,yMax]) + .numTicks(numTicksy) + .tickSize(tickSize) + .yAxisHighlight(yAxisHighlight) + .align(yAxisAlign) + .frameName(frameName); + + myYAxis1 + .rangeRound([currentFrame.dimension().height, 0]) + .domain( d3.range( 0, yMax + binWidth, binWidth ) ) + .align(yAxisAlign) + .frameName(frameName); + + + const background = currentFrame.plot().append('g'); // eslint-disable-line + + currentFrame.plot() + .call(myYAxis0); + + // return the value in the variable newMargin + if (yAxisAlign === 'right') { + const newMargin = myYAxis0.labelWidth() + currentFrame.margin().right; + // Use newMargin redefine the new margin and range of xAxis + currentFrame.margin({ right: newMargin }); + // yAxis.yLabel().attr('transform', `translate(${currentFrame.dimension().width},0)`); + } + if (yAxisAlign === 'left') { + const newMargin = myYAxis0.labelWidth() + currentFrame.margin().left; + // Use newMargin redefine the new margin and range of xAxis + currentFrame.margin({ left: newMargin }); + myYAxis0.yLabel().attr('transform', `translate(${(myYAxis0.tickSize() - myYAxis0.labelWidth())},0)`); + } + d3.select(currentFrame.plot().node().parentNode) + .call(currentFrame); + + myXAxis0 + .align(xAxisAlign) + .domain([xMin,xMax]) + .tickSize(currentFrame.rem()/2) + // .numTicks(numTicks) + .range([0, currentFrame.dimension().width]) + .frameName(frameName); + + myXAxis1 + .align(xAxisAlign) + .domain(d3.range( xMin, xMax + binWidth , binWidth ) ) + .rangeRound([0, currentFrame.dimension().width]); + + let colourDomain = []; + + if(typeof colourThresholds != 'undefined'){ + colourDomain = colourThresholds; + }; + + myChart + .xScale0(myXAxis0.scale()) + .xScale1(myXAxis1.scale()) + .yScale0(myYAxis0.scale()) + .yScale1(myYAxis1.scale()) + .plotDim(currentFrame.dimension()) + .selectedNames(selectedNames) + .rem(currentFrame.rem()) + .colourThresholds(colourDomain) + .colourPalette((frameName)); + + myAnnotations + .xScale0(myXAxis0.scale()) + .xScale1(myXAxis1.scale()) + .yScale0(myYAxis0.scale()) + .yScale1(myYAxis1.scale()) + .rem(currentFrame.rem()) + + + currentFrame.plot() + .call(myXAxis0); + + if (xAxisAlign === 'bottom') { + myXAxis0.xLabel().attr('transform', `translate(0,${currentFrame.dimension().height})`); + } + if (xAxisAlign === 'top') { + myXAxis0.xLabel().attr('transform', `translate(0,${-myXAxis0.tickSize()})`); + } + + + + + + currentFrame.plot() + .selectAll('.columnHolder') + .data(plotData) + .enter() + .append('g') + .attr('class', 'columnHolder') + .attr('data-name',d => d) + .call(myChart); + + background.append('rect') + .attr('width', currentFrame.dimension().width) + .attr('height', currentFrame.dimension().height) + .attr('fill', '#ededee'); + + const plotAnnotation = currentFrame.plot() + .append('g') + .attr('class', 'annotations-holder'); + + plotAnnotation + .selectAll('.annotation') + .data(plotAnnos) + .enter() + .append('g') + .call(myAnnotations); + + + + + }); + // addSVGSavers('figure.saveable'); + + + }); diff --git a/unit-histogram/parseData.js b/unit-histogram/parseData.js new file mode 100644 index 0000000..2b2539e --- /dev/null +++ b/unit-histogram/parseData.js @@ -0,0 +1,113 @@ +/** + * General data munging functionality + */ + +import * as d3 from 'd3'; +import loadData from '@financial-times/load-data'; + +/** + * Parses data file and returns structured data + * @param {String} url Path to CSV/TSV/JSON file + * @return {Object} Object containing series names, value extent and raw data object + */ +export function load(url, options) { // eslint-disable-line + return loadData(url).then((result) => { + const data = result.data ? result.data : result; + const { yMin, binWidth, highlightText } = options; // eslint-disable-line no-unused-vars + // make sure all the dates in the date column are a date object + + data.forEach((d) => { + d.value = +d.value + d.bin = Math.floor(d.value/binWidth) * binWidth; + }); + + console.log(highlightText) + + const bins = d3.range( d3.min(data, d=> d.bin),(d3.max(data, d=> d.bin) + binWidth ), binWidth); + + const names = arrayUnique(data.map(d => d.name)); + const selectedNames = names.filter( d => d.search(highlightText) > -1); + + const dataArray = []; + + bins.forEach(( bin, bindex ) => { + const dataInBin = data.filter(( d ) => { + return d.bin === bin + }); + + dataInBin.forEach( (e, j) => { + + let highlight = 'no'; + + if ( selectedNames.indexOf(e.name) > -1 || e.highlight == 'yes') { + highlight = 'yes' + } + + const binObj = { + name: e['name'], + bin: e['bin'], + value: e.value, + y: j, + highlight, + }; + + dataArray.push(binObj); + + + }) + }); + + const maxInBin = d3.max(dataArray, d => d.y); + + const plotData = d3.nest(dataArray) + .key(d => d.bin) + .entries(dataArray) + + + + + // Format the dataset that is used to draw the lines + + + // Sort the data so that the labeled items are drawn on top + + // Filter data for annotations + const annos = []; + + Object.keys(plotData).forEach(key => { + let vals = plotData[key].values; + + vals.forEach(v => { + + if(v.highlight == 'yes'){ + annos.push(v) + } + + }) + }); + + const plotAnnos = d3.nest(annos) + .key(d => d.bin) + .entries(annos); + // Format the data that is used to draw highlight tonal bands + + return { + bins, + selectedNames, + plotAnnos, + plotData + }; + }); +} + + function arrayUnique(array) { + return array.reduce(function(acc, cur) { + if (acc.indexOf(cur) < 0) acc.push(cur); + return acc; + }, []); + }; + + + + +