traccar / traccar-web

Traccar GPS Tracking System
https://www.traccar.org
Apache License 2.0
786 stars 1.09k forks source link

Feature Request: Reports use attribute "Web: Report Color" to display lines #1238

Open michalis97500 opened 1 month ago

michalis97500 commented 1 month ago

I'm always frustrated when trying to produce reports of several vehicles at the same time. All lines are drawn with the same blue color and thus distinguishing routes of different vehicles becomes extremely difficult

Each vehicle can get the color from its attribute as a way to display the routes in the reports.

No alternatives to this. The data must be exported, analyzed and plotted manually (maybe by python?) which defeats the purpose of the reports

michalis97500 commented 1 month ago

My solution to this is

In CombinedReportsPage.jsx

 // Define an array of colors
  const colors = [
    '#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF',
    '#FFA500', '#800080', '#008000', '#000080', '#FF4500', '#FF1493',
    '#00CED1', '#FFD700', '#8A2BE2', '#7FFF00', '#DC143C', '#00BFFF',
    '#FF69B4', '#32CD32', '#FF8C00', '#4B0082', '#ADFF2F', '#FF00FF',
    '#1E90FF', '#FFD700', '#FF6347', '#00FA9A', '#FFA07A', '#20B2AA',
    '#FFC0CB', '#7CFC00', '#BA55D3', '#FF4500', '#00FFFF', '#FF1493',
    '#00BFFF', '#FF69B4', '#32CD32', '#FF8C00', '#4B0082', '#ADFF2F'
  ];

  // Function to get a color for a device
  const getColorForDevice = (deviceId) => {
    const colorIndex = deviceId % colors.length;
    return colors[colorIndex];
  };

and modify MapRoutePath as :

                <MapRoutePath
                    key={item.deviceId}
                    name={devices[item.deviceId].name}
                    positions={item.positions}
                    coordinates={item.route}
                    color1={deviceColor}
                  />

then in MapRoutePath.js:

Modify this line to add color1


const MapRoutePath = ({ name, positions, coordinates, color1 }) => {

construct variable as:


const reportColor = useSelector((state) => {
    const position = positions?.find(() => true);
    console.log(`positions: ${positions}`); // Debug log
    if (position) {
      const attributes = state.devices.items[position.deviceId]?.attributes;
      console.log(`attributes: ${attributes}`); // Debug log
      if (attributes) {
        const color = color1;
        console.log(`color1: ${color1}`); // Debug log
        if (color) {
          console.log(`Returning Color: ${color}`); // Debug log
          return color;
        }
      }
    }
    if (color1) {
      console.log(`Returning Color: ${color1}`); // Debug log
      return color1;
    }
    return theme.palette.geometry.main;
  });

Add the color property as follows:


useEffect(() => {
    map.addSource(id, {
      type: 'geojson',
      data: {
        type: 'Feature',
        geometry: {
          type: 'LineString',
          coordinates: [],
        },
      properties: {
        color: reportColor,
      },
    },
    });
DanielNagy commented 1 month ago

Hi @michalis97500

color1={deviceColor}

where is deviceColor defined?

michalis97500 commented 1 month ago

@DanielNagy Apologies for missing this, I did it as :

{items.map((item) => { const deviceColor = getColorForDevice(item.deviceId); console.log(Device ID: ${item.deviceId}, Color: ${deviceColor}`); // Debug log

            return (
              <MapRoutePath
                key={item.deviceId}
                name={devices[item.deviceId].name}
                positions={item.positions}
                coordinates={item.route}
                color1={deviceColor}
              />
            );
          })}

`

the getColorForDevice() function is given in my previous comment. I would have posted the whole file for ease of use, but I modified some other parameters and tried to give code that can be easily added to the original file instead

DanielNagy commented 1 month ago

the getColorForDevice() function is given in my previous comment. I would have posted the whole file for ease of use, but I modified some other parameters and tried to give code that can be easily added to the original file instead

Great, I did do something smilar in the end.

For others following along, github broke the formatting above, here is a fixed version.

                {items.map((item) => { const deviceColor = getColorForDevice(item.deviceId); console.log(`Device ID: ${item.deviceId}, Color: ${deviceColor}`); // Debug log

                  return (
                    <MapRoutePath
                      key={item.deviceId}
                      name={devices[item.deviceId].name}
                      positions={item.positions}
                      coordinates={item.route}
                      color1={deviceColor}
                    />
                  );
                })}

Now to work out how to add Ant path function, instead of arrows to indicate direction. https://docs.mapbox.com/mapbox-gl-js/example/animate-ant-path/