|
| 1 | +--- |
| 2 | +category: examples |
| 3 | +group: pictogram chart |
| 4 | +title: SVG Shopping Mall Tenant Layout |
| 5 | +keywords: pictogramChart |
| 6 | +order: 26-5 |
| 7 | +cover: https://cdn.jsdelivr.net/gh/EchoChenGithub/images/mall_map.gif |
| 8 | +option: pictogramChart |
| 9 | +--- |
| 10 | + |
| 11 | +# SVG Shopping Mall Tenant Layout |
| 12 | + |
| 13 | +Shopping Mall Tenant Layout pictogram displays the distribution of different business formats within the mall. Each business format is represented by a specific shape, and the color of the shape indicates the type of business format. By using pictograms, we can quickly understand the mall's layout and business format distribution, providing a reference for mall operation and management. Hovering the mouse over the legend reveals the distribution of a specific business format; hovering the mouse over a shape in the diagram displays the name of the store corresponding to that shape. |
| 14 | + |
| 15 | +## Key Configurations |
| 16 | + |
| 17 | +- Register SVG resources through the `VChart.registerSVG` interface; |
| 18 | +- Declare the `svg` attribute as the registered SVG name. |
| 19 | +- Interaction: Disable the `select` configuration for the `legend`. Implement the hover highlight of legend items by listening to the mouse hover event of the legend, and then using the stateUpdate API `updateState`. You need to set the `state` for updating in the `pictogram` property. |
| 20 | +- data: Declare the data, the data format is `[{name: 'xxx', category: 'xxx'}]`. |
| 21 | + |
| 22 | +## Code Demo |
| 23 | + |
| 24 | +```javascript livedemo |
| 25 | +// Use the fetch API to get SVG graphic data |
| 26 | +const response = await fetch('https://cdn.jsdelivr.net/gh/EchoChenGithub/images/mallmap_withoutcolor.svg'); |
| 27 | +// Parse the response text content into an SVG graphic |
| 28 | +const shape = await response.text(); |
| 29 | + |
| 30 | +// Define mall data, including the name and category of each store |
| 31 | +const mall_data = [ |
| 32 | + { name: 'Starbucks', category: 'food_and_dining' }, |
| 33 | + { name: 'Foot Locker', category: 'apparel_and_shoes' }, |
| 34 | + { name: 'Dave and Busters', category: 'entertainment' }, |
| 35 | + { name: 'Best Buy', category: 'electronics' }, |
| 36 | + { name: 'Kay Jewelers', category: 'jewelry' }, |
| 37 | + { name: 'Target', category: 'shopping' }, |
| 38 | + { name: 'McDonalds', category: 'food_and_dining' }, |
| 39 | + { name: 'Nike Store', category: 'apparel_and_shoes' }, |
| 40 | + { name: 'AMC Theatres', category: 'entertainment' }, |
| 41 | + { name: 'Apple Store', category: 'electronics' }, |
| 42 | + { name: 'Tiffany Co', category: 'jewelry' }, |
| 43 | + { name: "Macy's", category: 'shopping' }, |
| 44 | + { name: 'Chipotle', category: 'food_and_dining' }, |
| 45 | + { name: 'Old Navy', category: 'apparel_and_shoes' }, |
| 46 | + { name: 'Samsung Store', category: 'electronics' }, |
| 47 | + { name: 'Pandora', category: 'jewelry' }, |
| 48 | + { name: 'Walmart', category: 'shopping' }, |
| 49 | + { name: 'Subway', category: 'food_and_dining' }, |
| 50 | + { name: 'Maintenance', category: 'infrastructure' }, |
| 51 | + { name: 'Restroom', category: 'infrastructure' }, |
| 52 | + { name: 'Management', category: 'infrastructure' }, |
| 53 | + { name: 'Adidas Store', category: 'apparel_and_shoes' }, |
| 54 | + { name: 'Round 1', category: 'entertainment' }, |
| 55 | + { name: 'HP Store', category: 'electronics' }, |
| 56 | + { name: 'Zales Jewelers', category: 'jewelry' }, |
| 57 | + { name: 'TJ Maxx', category: 'shopping' }, |
| 58 | + { name: 'Pizza Hut', category: 'food_and_dining' }, |
| 59 | + { name: 'HM', category: 'apparel_and_shoes' }, |
| 60 | + { name: 'Regal Cinemas', category: 'entertainment' }, |
| 61 | + { name: 'Microsoft Store', category: 'electronics' }, |
| 62 | + { name: 'Jared', category: 'jewelry' }, |
| 63 | + { name: "Kohl's", category: 'shopping' }, |
| 64 | + { name: 'Panera Bread', category: 'food_and_dining' }, |
| 65 | + { name: 'Gap', category: 'apparel_and_shoes' }, |
| 66 | + { name: 'Barnes and Noble', category: 'entertainment' }, |
| 67 | + { name: 'Radio Shack', category: 'electronics' }, |
| 68 | + { name: "Claire's", category: 'jewelry' }, |
| 69 | + { name: 'JCPenney Outlet', category: 'shopping' }, |
| 70 | + { name: 'Taco Bell', category: 'food_and_dining' }, |
| 71 | + { name: 'Express', category: 'apparel_and_shoes' }, |
| 72 | + { name: 'Chuck E Cheese', category: 'entertainment' }, |
| 73 | + { name: 'Swarovski', category: 'jewelry' }, |
| 74 | + { name: 'HomeGoods', category: 'shopping' }, |
| 75 | + { name: 'Burger King', category: 'food_and_dining' }, |
| 76 | + { name: 'American Eagle', category: 'apparel_and_shoes' }, |
| 77 | + { name: 'Sky Zone', category: 'entertainment' }, |
| 78 | + { name: 'Verizon', category: 'electronics' }, |
| 79 | + { name: 'Sephora', category: 'jewelry' }, |
| 80 | + { name: 'Best Buy Mobile', category: 'shopping' }, |
| 81 | + { name: 'Five Guys', category: 'food_and_dining' }, |
| 82 | + { name: "Levi's", category: 'apparel_and_shoes' }, |
| 83 | + { name: 'Arcade', category: 'entertainment' }, |
| 84 | + { name: 'GameStop', category: 'electronics' }, |
| 85 | + { name: 'Helzberg Diamonds', category: 'jewelry' }, |
| 86 | + { name: 'Marshalls', category: 'shopping' }, |
| 87 | + { name: 'Chick-fil-A', category: 'food_and_dining' }, |
| 88 | + { name: 'Banana Republic', category: 'apparel_and_shoes' }, |
| 89 | + { name: 'Main Event', category: 'entertainment' }, |
| 90 | + { name: 'Frys Electronics', category: 'electronics' }, |
| 91 | + { name: 'JCPenney Jewelers', category: 'jewelry' }, |
| 92 | + { name: 'Burlington', category: 'shopping' }, |
| 93 | + { name: 'Dunkin Donuts', category: 'food_and_dining' }, |
| 94 | + { name: 'Forever 21', category: 'shopping' }, |
| 95 | + { name: 'Mall Kiosk 1', category: 'shopping' }, |
| 96 | + { name: 'Mall Kiosk 2', category: 'food_and_dining' }, |
| 97 | + { name: 'Mall Kiosk 3', category: 'apparel_and_shoes' }, |
| 98 | + { name: 'Mall Kiosk 4', category: 'entertainment' }, |
| 99 | + { name: 'Mall Kiosk 5', category: 'electronics' }, |
| 100 | + { name: 'Mall Kiosk 6', category: 'jewelry' }, |
| 101 | + { name: 'Mall Kiosk 7', category: 'shopping' }, |
| 102 | + { name: 'JCPenney', category: 'apparel_and_shoes' }, |
| 103 | + { name: 'Belk', category: 'apparel_and_shoes' }, |
| 104 | + { name: 'Bealls', category: 'apparel_and_shoes' }, |
| 105 | + { name: 'Kmart', category: 'shopping' }, |
| 106 | + { name: 'AMC Theatres', category: 'entertainment' }, |
| 107 | + { name: 'Sears', category: 'shopping' } |
| 108 | +] |
| 109 | + |
| 110 | +// Define the chart configuration object |
| 111 | +const spec = { |
| 112 | + // Chart type is pictogram |
| 113 | + type: 'pictogram', |
| 114 | + data: { |
| 115 | + // The unique identifier of the data |
| 116 | + id: 'data', |
| 117 | + // The value of the data |
| 118 | + values: mall_data, |
| 119 | + }, |
| 120 | + color: { |
| 121 | + specified: { |
| 122 | + // The color of the food and dining category is brownish red |
| 123 | + food_and_dining: '#A52A2A', |
| 124 | + // The color of the apparel and shoes category is forest green |
| 125 | + apparel_and_shoes: '#228B22', |
| 126 | + // The color of the entertainment category is steel blue |
| 127 | + entertainment: '#4682B4', |
| 128 | + // The color of the jewelry category is dark violet |
| 129 | + jewelry: '#9400D3', |
| 130 | + // The color of the electronics category is goldenrod |
| 131 | + electronics: '#DAA520', |
| 132 | + // The color of the shopping category is dark cyan |
| 133 | + shopping: '#008B8B', |
| 134 | + // The color of the infrastructure category is dark olive green |
| 135 | + infrastructure: '#556B2F', |
| 136 | + // The color of the undefined category is white |
| 137 | + undefined: 'white', |
| 138 | + }, |
| 139 | + // The field for color mapping is category |
| 140 | + field: 'category' |
| 141 | + }, |
| 142 | + // The series field is category |
| 143 | + seriesField: 'category', |
| 144 | + // The name field is name |
| 145 | + nameField: 'name', |
| 146 | + // The name of the SVG graphic used is mall |
| 147 | + svg: 'mall', |
| 148 | + pictogram: { |
| 149 | + style: { |
| 150 | + fill: { |
| 151 | + // The fill color uses the color color mapping, and the field is category |
| 152 | + scale: 'color', |
| 153 | + field: 'category' |
| 154 | + } |
| 155 | + }, |
| 156 | + state: { |
| 157 | + // The fill color of the legend item when hovering is gray |
| 158 | + legend_hover_reverse: { |
| 159 | + fill: '#ccc', |
| 160 | + } |
| 161 | + } |
| 162 | + }, |
| 163 | + // Chart title |
| 164 | + title: { |
| 165 | + text: 'Shopping Mall Tenant Layout' |
| 166 | + }, |
| 167 | + legends: [ |
| 168 | + { |
| 169 | + orient: 'top', |
| 170 | + position: 'middle', |
| 171 | + padding: { |
| 172 | + bottom: 12 |
| 173 | + }, |
| 174 | + visible: true, |
| 175 | + field: 'category', |
| 176 | + filter: false, |
| 177 | + select: false, |
| 178 | + |
| 179 | + data: items => { |
| 180 | + return items.map(item => { |
| 181 | + item.shape.outerBorder = { |
| 182 | + stroke: item.shape.fill, |
| 183 | + distance: 2, |
| 184 | + lineWidth: 1 |
| 185 | + }; |
| 186 | + return item; |
| 187 | + }); |
| 188 | + }, |
| 189 | + } |
| 190 | + ], |
| 191 | +}; |
| 192 | + |
| 193 | +VChart.registerSVG('mall', shape); |
| 194 | + |
| 195 | +const vchart = new VChart(spec, { dom: CONTAINER_ID }); |
| 196 | + |
| 197 | +// Listen for the legend item hover event |
| 198 | +vchart.on('legendItemHover', e => { |
| 199 | + // Get the name of the hovered legend item |
| 200 | + const hoveredName = e?.value?.data?.label; |
| 201 | + if (hoveredName) { |
| 202 | + // Update the chart state to set the color of the non-hovered legend items to gray |
| 203 | + vchart.updateState({ |
| 204 | + legend_hover_reverse: { |
| 205 | + filter: d => { |
| 206 | + // Find the category of the current data item |
| 207 | + const category = mall_data.find(mall_data => mall_data.name === d.data?.name)?.category; |
| 208 | + // If the category exists and is not equal to the hovered legend item name, return true, otherwise return false |
| 209 | + return category && category !== hoveredName; |
| 210 | + } |
| 211 | + } |
| 212 | + }); |
| 213 | + } |
| 214 | +}); |
| 215 | + |
| 216 | +// Listen for the legend item unhover event |
| 217 | +vchart.on('legendItemUnHover', e => { |
| 218 | + // Update the chart state to restore the color of all legend items to the original color |
| 219 | + vchart.updateState({ |
| 220 | + legend_hover_reverse: { |
| 221 | + filter: d => false |
| 222 | + } |
| 223 | + }); |
| 224 | +}); |
| 225 | + |
| 226 | +vchart.renderSync(); |
| 227 | + |
| 228 | +// Just for the convenience of console debugging, DO NOT COPY! |
| 229 | +window['vchart'] = vchart; |
| 230 | +``` |
| 231 | +
|
| 232 | +## Related Tutorials |
| 233 | +
|
| 234 | +[PictogramChart](link) |
0 commit comments